a99  V32.6
allegro Windows Hauptprogramm
 Alle Klassen Dateien Funktionen Variablen Typdefinitionen Aufzählungen Aufzählungswerte Makrodefinitionen
a99.cpp
gehe zur Dokumentation dieser Datei
1 // a99.cpp : Hauptprogramm/-fenster a99/alcarta
2 // 1998/....
3 // Copyright 2012 Universitätsbibliothek Braunschweig, more see bottom
4 // Start: alcarta/a99 dann wird alcarta/a99.ini gelesen;
5 //
6 // alcarta/a99 xyz dann statt dessen xyz.ini
7 // alcarta/a99 filename dann "filename" = offline-datei,
8 // a99.ini wird gelesen
9 // alcarta/a99 0 dann file dialog zum Suchen einer INI
10 // 1 ... offline file (.?lg)
11 // 2 ... Datenbank (.?dx)
12 // Wenn Enter gedrückt wird, kommt OnDefault(), ist dabei der Focus in der
13 // Auswahlliste, dann OnOK()
14 
15 // Sehr grosse Quelldatei! Zustaendig fuer das gesamte Hauptfenster
16 // Enthaelt insbes. den FLEX-Interpreter, Funktion FLEXecute()
17 
18 // mit nichtmodalen Dialogen fuer Index (Winx) + FormularEditor (Aform)
19 
20 #include "program.h" // #define ALCARTA or #define A99, ND und ND2 (fuer a99a)
21 
22 // ACHTUNG: in program.h steht auch:
23 // #define DEMO // dann wird Groesse auf 1500 begrenzt
24 
25 char a99version[]="v32.5"; // VERSIONSNUMMER fuer var m
26 // In der Ressourcendatei a99.rc steht die "richtige" Vers.nr.
27 
28 // Den Programmnamen setzen (Ueberschrift einiger Fenster)
29 #ifdef A99
30 #define PRGN "a99"
31 #else
32 #define PRGN "alcarta"
33 #endif
34 
35 #include "stdafx.h"
36 #include "afxcoll.h" // for MapPtrToPtr
37 #include "afxtempl.h" // for MapPtrToPtr
38 #include "stdlib.h"
39 // For internet files
40 #include <afxinet.h>
41 
42 #define __GLOBALS // damit die allegro-Globals gesetzt werden:
43 #include "allegro.hpp"
44 #undef __GLOBALS
45 #include "ca99.h"
46 
47 #include "a99.h" // Hauptfenster
48 #include "winx.h" // Indexfenster
49 #include "wkv.h" // Kurz- und ViewListenfenster
50 
51 #include "warqa.h" // aresqa-Fenster
52 #include "wfind.h" // Find-Dialog (Fernglas)
53 #ifdef A99
54 #include "wglob.h" // Glob. Ersetzungsdialog
55 #endif
56 #include "aform.h" // Formularfenster
57 #include "subfield.h" // Subfield-Dialog
58 
59 #include "selbox.h"
60 #include "getl.h"
61 #include "getp.h"
62 #include "msg.h"
63 #include "aCleanup.h" // Besen
64 #include "regex.h" // regular expr search
65 #include <direct.h> // for _chdir
66 #include <process.h>
67 #include <share.h>
68 #include <math.h>
69 
70 
71 // Record status byte (in .TAB file = Reservespeicher)
72 #define CHG 1 // changed rec is active
73 #define DLT 2 // deleted
74 #define ONL 4 // online rec
75 #define SAV 8 // this rec was saved
76 #define NEW 16 // saved as new rec
77 
78 
79 // #define MAXR 264000 // max size of result set --> a99.h
80 
81 
82 #define WM_XECUTE WM_USER + 7 // event code for external flex cmd, program flex.exe
83 
84 #ifdef _DEBUG
85 #define new DEBUG_NEW
86 #undef THIS_FILE
87 static char THIS_FILE[] = __FILE__;
88 #endif
89 
90 
91 /////////////////////////////////////////////////////////////////////////////
92 // Globals for this module (schauderhaft, ja)
93 
94 int pid; // process id
95 
96 int accu=0; // access mode 0...4
97 int prnt=1; // 0: no printing
98 
99 int Skt=4; // for cfg value skt
100 
101 // For internet files f. InterOpen()
102 CInternetSession *Cif;
103 CStdioFile *Url;
104 
105 FILE *upload; // upload/update file
106 int updmdx=-1; // upd mode x DOS: update -fmxyz
107 int updmdy=0; // upd mode y
108 int updmdz=1; // upd mode z
109 int updmdp=0; // upd mode p : primkey
110 
111 char logName[128]; // path+name of cDX
112 char inxName[128]; // path+name of cDX
113 char inxParam[128]; // name of cPI
114 
115 char dataFont[64]; // name of data font
116 BYTE charSet; // character set
117 int FontSize=0;
119 
120 EXET *Dsp; // display param
121 EXET *Out; // export object
122 EXET *Out1; // 1st export object
123 EXET *Out2; // 2nd export object
124 EXET *Lox; // Long output list (PrintParam)
125 EXET *Gmp; // glob. Manip
126 
127 ABASE *BANK; // the database being used
128 ABASE *BANK2; // 2nd
129 ABASE *BANK3; // 3rd
130 
131 RECORD *Rec1; // 1st rec
132 RECORD *Rec2; // 2nd rec
133 
134 int rst1=0; // status Rec1/2
135 int rst2=4;
136 int Nrec1,Nrec2=-1; // nrec0 of Rec1/2
137  // nrec0 = number of current rec in offline store
138 
139 int adN=0; // Interne Index-Nummer des aktuellen Satzes
140 
141 double xiZ; // interne Zahl var Z (auch f. eval-Befehl)
142 long xiN; // interne Nummer var z
143 
144 CFont *aFont; // font for the text areas
145 CFont *bFont; // font for the text areas
146 LOGFONT lplf; // for data font
147 
148 CDC pDC; // print device context
149 BOOL PDC=0; // ==1 if we have a pDC
150 
151 CPrintDialog *cpd; // print dialog
152 PAGESETUPDLG psd; // for page setupping
153 
154 // auxiliary dialog objects - Unterfenster-Objekte
155 Wkv *wkv; // Kurz- und ViewListe
156 Warqa *warqa; // aresqa
157 Wfind *wfind; // find (Fernglas)
158 
159 #ifdef A99
160  Wglob *wglob; // Glob.Ersetzung nur in a99
161 #endif
162 
163 extern char *CmdLine; // start command of a99 : Wie wurde gestartet?
164 
165 char inifile[64]=""; // name of .INI or .INA
166 
167 extern int LookForDB(char *,char *,char); // gibt's die Datenbank? lookford.cpp
168 
169 #define MAXKAT 2000 // max Zahl Kategoriedeskriptoren + Abfrageliste
170 
171 CString Kat[MAXKAT]; // Field descriptors in CFG, for display in list
172 CString Abf[500]; // Abfrageliste nochmal extra
173 
174 RECNR result[MAXR]; // result set (list of rec#s)
175 RECNR family[1000]; // family
176 int anzFam=0; // size of fam
177 int MXRS=50; // not more than 50 result sets
178 
179 int rsize=0; // Size of result set
180 
181 int Esc=92; // ESC character for special characters
182 
183  // Flags
184 
185 bool bop=1; // database open, 0=closed
186 int xecflg=1; // 1: execute exflex allowed 2: no msg if failed
187 
188 int Rdo; // 1: Read-only mode in RTF window
189 long ecA, scA; // to prevent dupl. clicks calls in RTF window
190 int flipline=0; // line of last flip
191 
192 int spos=0; // Sort pos in result set window
193 int smod=0; // sort mode (0:ascend, 1=descend, 2=by rec#, 4=unsorted)
194 int emod=1; // error msg mode in FLEX, 0: no error msg
195 int xmod=0; // SR expand mode: expand every result set at once if 1
196 int Xmod=1; // Expansion in Find dialog (CMD) is set ON
197 char cmod='0'; // FLEX: e.adt is 0=ASCII 1=ANSI; Export mode
198 char dmod='+'; // -: \ nicht verdoppeln in eingebett. RTF-Variabl., set c+/c-
199 CHAR flm; // FlipMark, def. 160
200 
201 int hmod=0; // help mode, 0:normal 1:help page on display
202 
203 char jcod='j'; // JanaS code: jcod.htm is created, to be loaded by JanaS.exe
204 
205 int sfmod=0; // subfield mode (0: no subfield dialog)
206 int comod=1; // color mode (0: no color changes in display)
207 int capmod=0; // change index entries to uppercase if 1
208 int svmod=2; // save-mode: 1: save result sets and bookmarks
209 int savmd; // save record? 1=ask every time 0=ask 2=execute onput.flx
210 char afmod=0; // 1: auto flex mode
211 int hmd=0; // HelpMode 0: onhlpa99.flx
212 int vmod=0; // view mode: 0: no delete, 1:delete lines permitted
213 int Vmod=0; // visualize mode f. "flow", 1=jumps, 2=all, 0=nix
214 int srxmd=0; // regular expression search mode: 0=.ADX, p/q=export param
215  // which tables to use for coding!
216 bool fomod=TRUE;// input fields mode: FALSE = select all input, TRUE: caret at end, no select
217 
218 
219 int Fty=0; // file type, 1=pipe, 2=url
220 
221 bool i10a=true; // alcarta is allowed access to index 10?
222 
223 int closx=1; // Close index when focus goes to main window, 0=not
224 int setsize=0; // Set size according to INI
225 int dispsiz=22; // Size of display font 11 pt
226 int helpsiz=18; // Size of help font
227 int listsiz=18; // Size of list font
228 int longsiz=18; // Size of longlist font
229 int Fsize=-12; // Font size (8 point)
230 char Dfs='n'; // DispField size n=small b=big
231 int smax=10000; // max sort size for result sets
232 
233 int inputFi=1; // File for new records
234 long fileMax=0; // input file max size
235 
236 int opt_n; // mode for deleted records use (0,1,2)
237 
238 // watch out for RTF LIMIT !!!
239 char inpu[4000080]; // internal Variable (iV) for FLEX // RTF LIMIT
240 
241 char zeile[64000]; // auxiliary
242 char getzeil[4096]; // for GetL und Hilfszwecke
243 
244 CHAR w[32600]; // workstring, i.d.R. fuer neue Kategorien
245 CHAR wr[32600]; // Reserve: unveraend. Eingabestring vorher 8000
246 
247 CHAR ex[4000080]; // Export string: export text goes here first // RTF LIMIT
249 HGLOBAL EX;
250 
251 CHAR *ay[8000]; // 8000 line addresses for internal sorting
252 
253 struct tm *LocT; // Local Time structure for date calculations
254 
255 char flxnm[128]; // FLEX name aus Aufruf X name
256 
257 char aname[250]; // aresqa headline
258 char hname[255]; // name of help file
259 
260 int pty[256]; // for import character replacements (FLEX y a b)
261  // value <256: direct repl, else double-char via phrase
262 
263 char *Hname; // extra pointer for help name
264 char hlist[5000]; // list of recent help files
265 char *hptr; // pointer into this list
266 
267 char jobstore[256000];// FLEX space; Groesse auch beruecksicht. in FLEXecute() !
268 char *jp, *xc, *subi;// pointers into this
269 
270 int flxflg=0; // 1: FLEX definitely running, 2: special, 0: unclear
271 int fF=0; // 0: FLEX not running, 1:running (only for timerflex)
272 int answ; // yesno response etc. in FLEX // flag for if yes / no / cancel
273 
274 EDITSTREAM Rex; // for RTF-window
275 
276 int ei=0; // export index: position in putBuff
277 int dim=1; // display mode: 1:normal 0:label #-(
278 int brm=0; // browse mode: 0:normal 1:browse
279 int ixon=0; // 1/2 : index window 1/2 on (Alt+i/j)
280 
281 CHAR la[256]; // field label (help string for m_label)
282 char EdStart[20]; // default field for editing
283 char IxStart[100]; // default field for index startpoint
284 char IxShow[12]; // which indexes are available to user?
285 
286 
287 char srText[3000]; // Name of current result set
288 char srTerm[3000]; // search term from find field
289 char rpTerm[1000]; // replace term
290 char lsTerm[260]; // last index term
291 
292 // globale Ersetzungen
293 char gra[3][400]; // alter Inhalt
294 char grn[3][400]; // neuer Inhalt
295 char grf[3][10]; // im Feld ... (global repl fields)
296 
297 
298 char qbis[12]="@"; // separator for qrix command (von---bis)
299 
300 int reD, grE, blU; // Farbcodes
301 
302 #ifdef A99
303  int wihi=500; // window height
304 #else
305  int wihi=472; // alcarta weniger
306 #endif
307 // and width
308 int wiwi=772, wcx, wcy, dcx;
309 
310 
311 CHAR restri[64]; // current qualifier
312 
313  // Kalenderdaten: 10000 Bits fuer gut 25 Jahre
314 BOOL kal[10000];
315 int kp0=366; // 365 wenn Vorjahr nicht schalt
316 int kp=0;
317 
318 
319 // Struktur f. Inhalt des Fernglas-Fensters
320 struct Command // find command from the glob dialog
321 { // Inhalt des Fernglas-Formulars
322  int type;
323  char term1[200], term2[200], term3[200];
324  int ind1, ind2, ind3;
325  bool ex1, ex2, ex3, tr1, tr2, tr3;
326  int bool1, bool2;
327  int qua, op;
328  char term4[50];
329  int rad1;
330  } Com;
331 
332 
333 int Rmod=0; // Flag Restriktion ein/aus
334 int codflag=1; // Umkodierung ja (1) /nein (0)
335 long anzErg=0; // Anzahl der Treffer
336 CHAR ixname[90];// Indexname als default
337 
338 
339 CHAR jlab=0; // jump label : Sprungmarke nach korrekter Eingabe
340 
341 int inmo=0; // 1 or 0, 1:index open
342 
343 int limo = 1; // ListenModus (was steht in der Listbox?)
344  // 0 = Kategorieliste aus CFG
345  // 1 = Kategorien des aktuellen Satzes
346  // 2 = Hintergrundspeicher
347  // 3 = Result sets
348  // 4 = Abfrageliste
349 
350 char fowi = 0; // Where's the focus? (needed in OnOK())
351  // 1 = Listbox
352  // 2 = Write field
353  // 3 = srch cmd input field
354  // 4 = display window
355  // 5 = Edit, from export command #q
356 
357 char fomd = 0; // 0 = no form open
358  // 1 = form window is open
359 
360 char endfm= 1; // 1 = check form on [end] button
361  // 0 = don't check, user must press Enter on every field (old mode)
362 
363 int osm=0; // OnSelChange Modus: 1:SelChange laeuft (Rekursion vermeiden!)
364 int chf=0; // change flag: current rec was changed
365 int nrw=0; // nr of recs written (anz. geschriebene Saetze)
366 int nro=0; // nr of OFFLINE records changed/written/saved
367  // wenn >0: Datei muss am Ende reorg. werden
368 int nrs=0; // nr records saved to database
369 int noe=0; // nr online records edited
370 int nnw=0; // nr new records
371 int out=0; // output: number of recs
372 int rss=0; // number of result sets
373 int rsx=3; // # of current result set
374 int rwu=0; // if >0: result set was used
375 
376 int Shft=0; // Shift to the right in wkv display (frueher: brief list)
377 char Bpos[6]; // starting position in wkv list, e.g. "245" for #245
378 
379 
380 // Dateien
381 
382 FILE *edF; // Datei zum Editieren (.alg oder .adt) bleibt unveraendert
383 FILE *rdF; // Datei zum Einlesen (.alg oder .adt) edF oder nwF
384 FILE *nwF; // Datei fuer Neusaetze(.alg oder .adt) Schreib/Lese "OfflineDatei"
385 FILE *xdF; // Datei zum externen Bearb. eines Satzes
386 FILE *atF; // Adressentabelle; atF!=0 heisst: es gibt eine
387 FILE *ouF; // output files
388 FILE *ouF1,*ouF2;
389 FILE *rsF; // result set numbers file
390  // format: Offline: 2bytes per rec#, hi/lo
391  // Online: 4
392 FILE *vwF; // view file (.VW)
393 int rsn=0; // # of current rec in result set
394 int vwn=0; // # of current rec in view
395 int vwz=0; // view size
396 int vwl; // view line leng
397 
398 FILE *rs1; // Bookmarks
399 FILE *rs2; // History file
400 int rn0=0; // index in rs2 (for Back/Forward)
401 RECNR rn1=0; // number of last bookmark added
402 RECNR rn2=0; // number of last rec added to hist
403 RECNR rn3=0; // number chosen from res set
404 
405 // Datei- u. Ordnernamen
406 
407 char cwD[128]; // current working dir
408 char edfN[128]; // Name of input file
409 char nwfN[128]; // Name of new file (temporary!)
410 char nwfNR[128];// Name of new file (temporary!, reserve)
411 char atfN[128]; // Name of .TAB file
412 char *outN; // Name of current output file
413 char outN1[128];// Name of 1st output file
414 char outN2[128];// Name of 2nd output file
415 char outN0[128];// Name of output file, backup
416 char extN[128]; // Name of external edit file
417 char *expN; // Name of current export param
418 char expN1[128];// Name of 1st export param
419 char expN2[128];// Name of 2nd export param
420 char dspN[128]; // Name of display param
421 char prnN[128]; // Name of print param
422 char phrN[128]; // Name of phrase file
423 char rssN[128]; // Name of result set numbers file
424 char rssNB[128];// BaseName of result set numbers file
425 char frmN[128]; // Name of input forms file
426 char viwN[128]; // Name of view file
427 char gmpN[128]; // Name of global manip param
428 char sflX[32]; // Name of start FLEX, default
429 
430 // for JanaS
431 char JemP[128]; // Name of TEMP dir (for JanaS)
432 
433 unsigned int Jmsg=0; // JanaS event number for this process
434 
435 
436 int frm[250]; // numbers of forms in phrase space, starting 25000
437  // form n begins at phrase 25000 +(n-1)*28
438 int frmn=0; // how many forms
439 
440 char konfig[128]; // Konfig name
441 
442 // pgDir[] ist definiert in allegro.hpp
443 
444 char HelpDir[128]; // Help directory
445 char FlexDir[128]; // FLEX directory
446 
447 char dtDir[128]; // data directory
448 char basN[64]; // File name without path
449 char dbN[17]; // database name
450 char dbN2[17]; // 2nd database name
451 char dbN3[17]; // 3rd database name
452 char dbDir[128]; // database directory
453 char dbDir2[128]; // 2nd database directory
454 char dbDir3[128]; // 3rd database directory
455 char dbT[120]; // database Title
456 char dbAux[128]; // auxiliary user dir
457 char dbBack[128]; // database backup directory
458 
459 char helphead[2000]; // for helpfiles, RTF header
460 char disphead[2000]; // for record display
461 char listhead[2000]; // for wkv list
462 char longhead[2000]; // for full list
463 
464 int rtfpos; // position in rtf stream
465 
466 int wrflag=1; // 0 : no write access
467 
468 int docT=0; // doc type: 0=.ALG 1=.ADT 2=.ALD
469 int resT; // result set type: 0=offline 1=online
470 int fsi=0; // offline file size, # of records
471 int fsi0=0; // size at start
472 long fSize; // file size in bytes at start
473 int nrb=0; // last browse pos in result set
474 int nbom=0; // nr of bookmarks
475 
476 int extflg=1; // extern flag: 0 : no external editing
477 
478 char editor[128]; // Name of external editor
479 
480 extern long NewSearch(char *eing, RECNR *pResultSet,long lMaxRes, char ex);
481 // extern int Auftrag(char *,RECNR result[],ABASE *Bank,int);
482 extern int WhichRestr(ABASE *, char*);
483 
484 
485 extern int ffil(char *tmplt,char *fff); // find files tmplt, write names to fff, separator 20
486 
487 
488 void tabOut(long rp,char D, long np=0L); // write rp to tab file at current position
489 
490 WINDOWPLACEMENT mwplace; // for main window
491 WINDOWPLACEMENT brplace; // for wkv.cpp!
492 WINDOWPLACEMENT adplace; // for aform.cpp!
493 WINDOWPLACEMENT dwp; // for display
494 WINDOWPLACEMENT arplace; // for aresqa (warqa.cpp)
495 
496 // for global user variables ($ var.)
497 CMapStringToString uvA, uva;
498 POSITION vA, va;
499 CString uvn, uvc;
500 // WfindReplaceDialog *cfr=0; // for find/repl message
501 // UINT wm_Find=0;
502 
503 
504 // **************************
505 // a99 proprietary functions
506 
507 char timerflex[256]="0";
508 
509 void CALLBACK EXPORT TimerProc(
510  HWND hWnd, // handle of CWnd that called SetTimer
511  UINT nMsg, // WM_TIMER
512  UINT nIDEvent, // timer identification
513  DWORD dwTime // system time
514  )
515 {
516  extern a99 *dlg; // main dialog
517  int fow=fowi;
518  if(*timerflex=='0') { dlg->KillTimer(nIDEvent); return; }
519  if(!fF) // nur wenn gerade kein anderer FLEX laeuft
520  {
521  dlg->FLEXecute(timerflex+1);
522  if(*timerflex=='1') dlg->KillTimer(nIDEvent);
523  if(fow==2) dlg->m_enter.SetFocus();
524  }
525  return;
526 }
527 
528 
529 
530 int viewEql(int zl)
531 {
532  // equalize lines of a view file
533 
534  char vn[128]; FILE *vF;
535  int i; char *k;
536  strcpy(vn,viwN); strcat(vn,"n");
537  if((vF=fopen(vn,"wb"))==NULL) return 0; // neue Datei
538  fseek(vwF,0L,0);
539  while(1)
540  {
541  k=fgets(zeile,255,vwF);
542  if(!k) break;
543  UtRemsp((CHAR *)zeile);
544  i=strlen(zeile);
545 // if(i<=0) continue; // line empty
546  if(i>zl-2)
547  { fclose(vF); fseek(vwF,0L,0); vF=fopen(vn,"wb"); zl=i+2; continue; }
548  while(i<zl-2) zeile[i++]=' ';
549  zeile[i]=0;
550  fprintf(vF,"%s\r\n",zeile);
551  }
552  fclose(vwF); fclose(vF);
553 // unlink(viwN); // alte Datei loeschen
554 // rename(vn,viwN); // neue Datei -> alter Name, und wieder oeffnen
555  strcpy(viwN,vn);
556  if(!(vwF=_fsopen(viwN,"r+b",_SH_DENYNO))) return 0; // $$081215
557  return zl;
558 }
559 
560 
561 int days(int d)
562 {
563  // Tag des Jahres, heute +d Tage, d kann <0 sein!
564 
565  time_t ac;
566  time(&ac); // aktuelle Zeit in sekunden
567  ac+=(time_t)(d*24*3600); // + Tage*Sekunden
568  LocT=localtime(&ac); // umrechnen in tm-Struktur
569  if(!LocT) { ac=0; LocT=localtime(&ac); }
570  return LocT->tm_yday+1; // Tage seit 1 Jan. Dabei gilt 1.Jan = 0 !
571 }
572 
573 
574 int Dates(char *dt)
575 {
576  // Rueckgabe: JJJJMMTT/00:00:00 = day, TT. month, year
577  char *d;
578  char *Day[]={ "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa" };
579  char *Mon[]={ "Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez" };
580  int yf=0;
581  char year[5], mon[3], day[3];
582  if(strlen(dt)<8) { *inpu=0; return 0; }
583  strncpy(year,dt,4); strncpy(mon,dt+4,2); strncpy(day,dt+6,2);
584  year[4]=0; mon[2]=day[2]=0;
585  int yr=atoi(year); int mn=atoi(mon); int dy=atoi(day);
586 // Jahr >2037: 56 weniger, denn 1982 kalendertechnisch = 2038
587  if(yr>2099) { sprintf(inpu,dt); return 0; }
588  if(yr<1971) { yr+=56; yf=-56; }
589  if(yr<1971 && yr>1901) { yr+=56; yf-=56; }
590  if(yr>2037) { yr-=56; yf=56; }
591 // nochmals -56, wenn immer noch >2037. Klappt aber nur bis 2099, da 2100 kein Schaltjahr
592  if(yr>2037) { yr-=56; yf=112; }
593  if(yr<1970 || yr>2037) { sprintf(inpu,dt); return 0; }
594  CTime ct(yr,mn,dy,0,0,0,0); // letzte 0: nDST DaylightSavings not set
595 // Kommt + oder - in dt vor?
596  if((d=strchr(dt,'+'))!=0) ct += CTimeSpan(atoi(d+1),2,0,0);
597  else if((d=strchr(dt,'-'))!=0)
598  { int diff=atoi(++d);
599  if(diff<1900) // Datum - Tage = Datum
600  ct -= CTimeSpan(diff-1,5,0,0);
601  else // Datum1 - Datum2 = TimeSpan
602  {
603  strncpy(year,d,4); strncpy(mon,d+4,2); strncpy(day,d+6,2);
604  year[4]=0; mon[2]=day[2]=0;
605  int yr=atoi(year)-yf; int mn=atoi(mon); int dy=atoi(day);
606  CTimeSpan ts = ct - CTime(yr,mn,dy,1,0,0) ; // 1: sonst 20070607-20070606 = 0
607  yf=ts.GetDays(); if(ts.GetHours()==23) ++yf; // 1 Tag mehr, wenn positiv
608  sprintf(inpu,"%d",yf); // Nur die Tage zurueckgeben
609  return 1;
610  }
611  }
612 // errechnetes Datum -> inpu, Form: JJJJMMTT/00:00:00 = day, TT. month, year
613  sprintf(inpu,"%d%02d%02d/00:00:00 = %.2s, %d. %.3s %d",ct.GetYear()+yf,ct.GetMonth(),ct.GetDay(),Day[ct.GetDayOfWeek()-1],ct.GetDay(), Mon[ct.GetMonth()-1],ct.GetYear()+yf);
614  return yr;
615 }
616 
617 FILE *fOpen(char *fnam, char *mode, char *hdir=0)
618 {
619  // open a file, searching on several paths
620  FILE *fi;
621  Hname=zeile+300;
622  sprintf(Hname,"%s%s",dbDir,fnam); // 1st dbDir
623  fi=_fsopen(Hname,mode,_SH_DENYNO);
624 
625  if(fi) ;
626  else if(!strchr(fnam,*fsep))
627  {
628  if(hdir)
629  {
630  if(strchr(hdir,92))
631  sprintf(Hname,"%s\\%s",hdir,fnam); // pgDir\hdir
632  else
633  sprintf(Hname,"%s%s\\%s",pgDir,hdir,fnam); // pgDir\hdir
634  fi=_fsopen(Hname,mode,_SH_DENYNO);
635  }
636  if(!fi)
637  {
638  sprintf(Hname,"%s%s",pgDir,fnam); // 2nd pgDir
639  fi=_fsopen(Hname,mode,_SH_DENYNO);
640  }
641  }
642  if(!fi && (accu>3 || flxflg)) // Sicherheit!
643  { strcpy(Hname,fnam);
644  fi=_fsopen(fnam,mode,_SH_DENYNO); // 3rd real name
645  }
646 // if(fi && hdir==HelpDir) strcpy(hname,Hname);
647 // if(!strstr(Hname,".flx"))
648 // if(fi) strcpy(hname,Hname);
649 // else *hname=0;
650  return fi;
651 }
652 
653 
654 int outOpen(void)
655 {
656  // open OutputFile, name is in outN
657  if(ouF) return 1;
658  if(!*outN) strcpy(outN,".\\output.adt"); // 1st time
659  if(*outN=='+') strcpy(outN,outN+1); else if(!out) unlink(outN);
660  ouF=fopen(outN,"a+b");
661  if(!ouF) ouF=fopen(outN,"w+b"); // for binary write
662  if(!ouF) return 0;
663  return 1;
664 }
665 
666 // Zeichenausgabefunktionen. Jedes EXET braucht eine
667 
668 int putedit(int a)
669 {
670  // Zeichen-Ausgabefunktion fuer Downloads
671  return fputc(a,edF);
672 }
673 
674 int putadt(int a)
675 {
676  // Zeichen-Ausgabefunktion fuer Dateityp .ADT
677  return fputc(a,nwF);
678 }
679 
680 int putout(int a)
681 {
682  // Zeichen-Ausgabefunktion fuer Export
683  return fputc(a,ouF);
684 }
685 
686 int putoutA(int a)
687 {
688  // Zeichen-Ausgabefunktion fuer Export, ANSI
689  int i=a;
690  i=BANK->etb[0][(unsigned)i];
691  return fputc(i,ouF);
692 }
693 
694 int putxdit(int a)
695 {
696  // Zeichen-Ausgabefunktion fuer Downloads in E.DAT
697  return fputc(a,xdF);
698 }
699 
700 int noOutput(int i)
701 {
702  // no output - keine echte Ausgabe
703  return i; }
704 
705 
706 // Funktionen fuer Daten im Arb.-Speicher
707 
708 int fadr(CHAR *kat, int lg=4)
709 {
710  // find kat="#uxy" in background store, ret index
711  int i=0;
712  while(i<fri)
713  if(strncmp((char *)fa[i],kat,lg)) ++i; else break;
714  if(i<fri) return i;
715  else return -1;
716  }
717 
718 void crypt(char *inpu)
719 {
720  // encrypt the string (irreversible!)
721  char cy[53]="zxvtrpnljhfdbeacgikmoqsuywzxrpnljhbdfeacgikmoqsuywtv";
722  int i=strlen(inpu)-1; int j;
723  CHAR *a=(CHAR *)inpu;
724  j=0;
725  CHAR c=*a; strcpy(inpu,inpu+1); inpu[i]=c; inpu[i+1]=0;
726  while(*a) { *a=(*a+j)%26; ++a; j+=7; }
727  c=cy[(c+i)%52]%26;
728  while(i>-1) { inpu[i]=cy[inpu[i]+c]; --i; }
729 }
730 
731 void addhelp(char *he,int pm)
732 {
733  // add a name to hlist
734  if(*he=='_' || *he=='=' || *he=='>') return;
735  if(strlen(hlist)+strlen(he)>4900) // danger! make shorter
736  {
737  char *a; a=hlist+100;
738  while(*a!='|') ++a;
739  strcpy(hlist,a);
740  }
741 // hptr=hlist+strlen(hlist);
742  char *p;
743  if(*hptr) --hptr;
744  else
745  {
746  p=hptr;
747  while(*p!='|') --p;
748  ++p;
749  if(!strcmp(p,he) && !pm) return; // same name as before
750 
751  if(pm)
752  { char *q;
753  q=strchr(p,'=');
754  if(!q) p=strchr(p,'#'); else p=q;
755  if(p) hptr=p;
756  sprintf(hptr,"#%d",pm);
757  hptr+=strlen(hptr);
758  sprintf(hptr,"|%s",he);
759  hptr+=strlen(hptr);
760  return;
761  }
762  }
763 
764  sprintf(hptr,"|%s",he);
765  hptr+=strlen(hptr);
766 } // ENDE addhelp()
767 
768 
769 void flipcode(char *f)
770 {
771  // decode a flip line (rtf help text)
772  // Umlaute umwandeln in ASCII, andere Sonderzeichen bleiben!
773  int i=0; char *a;
774  a=f;
775  while(*a)
776  {
777  if(*a=='\\' && a[1]==39)
778  { a+=2;
779  if(*a=='e') f[i++]=132; // ae
780  if(*a=='c') f[i++]=142; // Ae
781  if(*a=='f')
782  { if(a[1]=='6') f[i++]=148; // oe
783  else f[i++]=129; // ue
784  }
785  if(*a=='d')
786  { if(a[1]=='f') f[i++]=225; // ss
787  if(a[1]=='6') f[i++]=153; // Oe
788  else if(a[1]=='c') f[i++]=154; // Ue
789  }
790  ++a;
791  }
792  else if(*a=='`') f[i++]='\\'; /* ` in a Flip, --> \ */
793  else f[i++]=*a;
794  ++a;
795  }
796  f[i]=0;
797 }
798 
799 void stresc(char *f)
800 {
801  // escape codes for { \ } in rtf lines
802  char fy[360];
803  int i=0, j=0;
804  while(f[i])
805  {
806  if(strchr("{\\}",f[i])) fy[j++]='\\';
807  fy[j++]=f[i++];
808  }
809  fy[j]=0;
810  strcpy(f,fy);
811 }
812 
813 void remcom(CHAR *a)
814 {
815  // remove comments preceded by 2 spaces, xcpt ", "
816  int i=0; CHAR r[250]; CHAR *s; s=r;
817  while(a[i]) if(a[i++]==QT && a[i-2]!='+') while(a[i] && a[i++]!=QT);
818  else if(a[i-1]==39 && a[i-2]!='+') while(a[i] && a[i++]!=39); /* single Quote */
819  else if(isspace(a[i-1]) && isspace(a[i]) && a[i-2]!=',')
820  {
821  strcpy(r,a+i+1);
822  // while(*s==' ') ++s; restliche Leerz. wegnehmen??
823  strcpy(a+i," //--");
824  strcat(a,s);
825  break;
826  }
827  return;
828  }
829 
830 void isbnhyp(char *tx)
831 {
832  // isbn: insert hyphens, txp->atc
833  int k=0, i=0, j=0;
834  char at[20]; char *atc=at, *txp=tx;
835  if(!strncmp(tx,"978",3) || !strncmp(tx,"978",3))
836  { strncpy(atc,txp,3); atc+=3; *atc++='-'; txp+=3; }
837  *atc++= *txp++; /* 1. Ziffer 8 oder 9? */
838  if(atc[-1]=='9') { k=2; *atc++=*txp++; *atc++=*txp++; }
839  else if(atc[-1]=='8') { k=1; *atc++=*txp++; }
840  *atc++='-';
841  switch(*txp)
842  { case '1':
843  case '0':
844  i=2; break;
845  case '2':
846  case '3':
847  case '4':
848  case '5':
849  case '6':
850  i=3; break;
851  case '7':
852  i=4; break;
853  case '8':
854  if(txp[1]<'5') i=4; else i=5;
855  break;
856  case '9':
857  if(txp[1]<'5') i=6; else i=7;
858  break;
859  }
860  j=8-i-k;
861  while(i-->0) *atc++=*txp++;
862  *atc++='-';
863  while(j-->0) *atc++=*txp++;
864  *atc++='-'; *atc++=*txp++;
865  *atc=0;
866  strcpy(tx,at);
867  }
868 
869 
870 CHAR *get_text(FILE *fh,CHAR *a,int j, CHAR *cend)
871 {
872 /* read text from a file until end or string found
873  get text from fh to addr a, until EOF
874  or until cend is encountered
875  cend = end string */
876  static int i; static long posit; static int pm;
877  static CHAR *sd; signed char cis; CHAR cic; static unsigned int LEN;
878  bool pmode=0; CHAR end[64]; // pmode=1: add space after . if letter follows
879  memmove(end,cend,j);
880  LEN=256000; /* $$980221 Sicherheit */
881  sd=a; *a=0;
882  pm=0;
883  cis=fgetc(fh);
884  if(cis==EOF) return 0;
885  do
886  { cic=cis;
887 // cic=pty[cic]; if(cic==26) continue; // 26 = skip
888  if(pm && pmode && isalpha(cic)) *sd++=' ';
889  *sd++=cic;
890  if(cic=='.') pm=1; else pm=0;
891  if(cic==*end)
892  { i=1; posit=ftell(fh); /* this is the nxt char */
893  while(i<j && (cis=fgetc(fh))!=EOF)
894  { cic=cis;
895 // cic=pty[cic]; if(cic==26) continue; // 26 = skip
896  *sd++=cic;
897  if (cic!=end[i]) if(end[i]!='?') break; // ? wildcard
898  ++i;
899  }
900  if(i==j || cis==EOF) break;
901  fseek(fh,posit,0); /* reposition read pointer */
902  sd-=(i); /* and text pointer */
903  }
904  if(sd-a>LEN) /* MaxLaenge ueberschritten */
905  { *Aerror='-';
906  return 0;
907  }
908  }
909  while((cis=fgetc(fh))!=EOF);
910 
911  i=-1;
912  if(cis==EOF) { *sd=NL; return 0; }
913  sd[-j]=NL;
914  return sd-j; /* result: addr behind text, excluding end-string */
915 } // ENDE get_text()
916 
917 
918 
919 bool itrans(CHAR *sour, CHAR *targ, int n)
920 {
921  // write n byte from sour to targ
922  // Import coding using table pty [s.a. import.c : atrans() ]
923  // FLEX y... : wie in import.c
924  // executing 2-byte conversions
925  CHAR *adr, *trg, *gy, *gz; CString uvn,uvc;
926  CHAR ca, pt, i; char Pro[4]="Z]x";
927  adr=sour; trg=targ;
928  if(n<0) return false;
929  while(n-- >0) if(pty[*adr]<256) *trg++=pty[*adr++];
930  else /* protype handling, ?o = Umlaut oe */
931  { pt=pty[*adr++]-256;
932  if(pt) // code is not 0 (i.e., not y x 256
933  {
934  ca=*adr++; // ca = char behind protype
935  if(!ca) { *trg++=adr[-2]; *trg=NL; return true; } /* protype is last char in field */
936  Pro[2]=(char )pt; uvn=Pro;
937  if(uvA.Lookup(uvn,uvc)) strcpy(wr,LPCTSTR(uvc)); else return false; // protype not found
938  strcat(wr," "); // sicherheit
939  gy=wr;
940  gz=(CHAR *)strchr(gy,' ')+1; gz[-1]=0;
941  i=0; while(ca!=gy[i] && gy[i]!=NL) ++i;
942  if(gy[i]) *trg++=gz[i];
943  else *trg++=*(adr-2),*trg++=ca;
944  --n;
945  }
946  }
947  *trg=NL;
948  return true;
949 }
950 
951 // ******************************
952 // Internet files access routines
953 
954 int InterGetFile(char *url, char *buf,int buflen)
955 {
956  // Internetdatei komplett einlesen, FLEX get Iurl oder var Furl
957  char *ip, *bf; int bl=4000000; // max 4MB
958  CInternetSession *Cif;
959  CStdioFile *Url;
960 
961 // Es wird ein Browser-Objekt angelegt, das sich als Mozilla ausgibt
962 TRY
963  Cif = new CInternetSession("Mozilla/5.0 (Windows NT 6.1; rv:13.0) Gecko/20100101 Firefox/13.0 ");
964  if(buflen) bl=buflen;
965  ip=url; while(isspace(*ip)) ++ip; // leading spaces
966  if(!*ip) ip=inpu; // get I and url is in inpu
967  Url= Cif->OpenURL(ip,1,INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_PASSIVE | INTERNET_FLAG_DONT_CACHE);
968 CATCH( CInternetException, e )
969  return -1;
970 END_CATCH
971 
972 // Achtung: Funktion wird hier abgebrochen, wenn Datei nicht existiert...
973 // sogar der FLEX wird ganz abgebrochen - Abhilfe unbekannt.
974 
975  if(!Url) { delete Cif; return -1; }
976  if(!buf) bf=inpu; else bf=buf;
977  *bf=0; // now read
978  // am Zeilenende wird 13 beseitigt, nur 10 bleibt! wird korrigiert
979  while(strlen(bf)<bl && Url->ReadString(bf+strlen(bf),20000))
980  { ip=bf+strlen(bf)-2; if(*ip!=13) sprintf(ip+1,"\r\n"); }
981  Url->Close();
982  Cif->Close();
983  delete Cif;
984  Cif=0;
985  if(strlen(bf)<bl) return 0;
986  return 1; // there was more - buf too short
987 }
988 
989 int InterOpen(char *url)
990 {
991  // Internetdatei oeffnen mit open http:// ...
992  char *ip;
993  ip=url; while(isspace(*ip)) ++ip; // leading spaces
994  if(!*ip) ip=inpu; // get I and url is in inpu
995  Cif = new CInternetSession();
996 TRY
997  Cif = new CInternetSession();
998  Url= Cif->OpenURL(ip,1,INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_PASSIVE | INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_KEEP_CONNECTION);
999 CATCH( CInternetException, e )
1000  return -1;
1001 END_CATCH
1002  if(!Url) { Cif->Close(); delete Cif; return -1; }
1003  return 0;
1004 }
1005 
1007 {
1008  // die geoeffnete Internetdatei schliessen
1009  if(Url) Url->Close();
1010  if(!Cif) return;
1011  Cif->Close();
1012  delete Cif;
1013  Cif=0;
1014 }
1015 
1016 int InterGet(char *adr)
1017 {
1018  // aus der geoeffneten Internetdatei nach adr lesen
1019  char *ip;
1020 
1021  if(!Cif || !Url) return -1;
1022  ip=adr;
1023  *ip=0; // now read
1024  // am Zeilenende wird 13 beseitigt, nur 10 bleibt! wird korrigiert
1025  if(Url->ReadString(ip,8192)) return 1; else return 0;
1026 }
1027 
1028 int InterRead(int bn)
1029 {
1030  // aus der geoeffneten Internetdatei bn Bytes lesen
1031  int in,q=0; char *ip, *np; ip=zeile; np=inpu;
1032  if(!Cif || !Url) return -1;
1033  in=Url->Read(ip, bn); // in Zeichen sind gelesen
1034  if(in<1) return in;
1035  while(q<in)
1036  {
1037  if(ip[q]<32) { *np++='^'; *np++=ip[q]+64; }
1038  else if(ip[q]=='^') { *np++='^'; *np++='~'; }
1039  else *np++=ip[q];
1040  ++q;
1041  }
1042  *np=0;
1043  return in;
1044 }
1045 // ****************************** END internet access
1046 
1047 
1048 // =========== //
1049 // a99 Methods //
1050 // =========== //
1051 
1052 void a99::RecMerge(RECORD *Satz1, RECORD *Satz2)
1053 {
1054  // Merge Satz1 into Satz2
1055  int i=0,j=0;
1056  Satz1->cri=Satz2->cri=0;
1057  while(i<Satz1->gri)
1058  if(Satz1->gi[i]>3 && Satz1->gi[i]<8) break; // subr
1059  else
1060  { if(Satz1->ga[i][Cfg->skt]==')') Satz1->ga[i][Cfg->skt]='~'; // new multifield
1061  Satz2->Ins(Satz1->ga[i++]);
1062  }
1063  // XXX Subrecs 1 -> 2
1064  while(i<Satz1->gri)
1065  {
1066  j=Satz2->SubPos(Satz1->ga[i]+2); // find subrec
1067  if(j==-1) j=Satz2->gri;
1068  Satz2->cri=j;
1069  Satz2->Ins(Satz1->ga[i++]+2);
1070  while(i<Satz1->gri)
1071  if(Satz1->gi[i]>3 && Satz1->gi[i]<8) break; // subr
1072  else
1073  {
1074  if(Satz1->ga[i][Cfg->skt]==')') Satz1->ga[i][Cfg->skt]='~'; // new multifield
1075  Satz2->Ins(Satz1->ga[i++]);
1076  }
1077  }
1078  Satz1->cri=Satz2->cri=0;
1079  return;
1080 } // ENDE RecMerge()
1081 
1083 {
1084  // clear offline store
1085  Rx.RemoveAll();
1086  fclose(nwF); // delete .$$$
1087  nwF=fopen(nwfN,"w+b");
1088  fputc(1,nwF); // mind. 1 Zeichen muss drin sein
1089  fclose(atF);
1090  atF=fopen(atfN,"w+b"); // overwrite .TAB !
1091  nrec1=fsi=fsi0=0;
1092  if(nrec || !Rec->rNr) dbFetch(1L,0);
1093 }
1094 
1095 
1096 
1097 void a99::gvar(char *na)
1098 {
1099  // get variable $na, copy text to zeile
1100  CString uvn,uvc;
1101  char name[64]; // Name of $-variable
1102  int j=0;
1103  while((name[j]=na[j]) && !strchr(" ($",name[j])) ++j;
1104  *zeile=name[j]=0; uvn=name; // now : name = xyz *zeile=0; uvn=name;
1105  if(*name>'?' && *name<'`') // @ A..Z [ \ ]
1106  { if(uvA.Lookup(uvn,uvc)) strcpy(zeile,LPCTSTR(uvc)); }
1107  else if(uva.Lookup(uvn,uvc)) strcpy(zeile,LPCTSTR(uvc));
1108  if(j<strlen(na) && na[j]=='$') // $Name$x Teilfeld!
1109  {
1110  char *vn;
1111  char sf[3]; sf[2]=0; *sf=Cfg->SF; sf[1]=na[j+1];
1112  if(sf[1]=='$') { vn=strchr(zeile,31); if(vn) *vn=0; } // $name$$
1113  else if(vn=strstr(zeile,sf))
1114  { strcpy(zeile,vn+2); if(vn=strchr(zeile,Cfg->SF)) *vn=0; } // $name$x
1115  else *zeile=0;
1116  }
1117  return;
1118 }
1119 
1120 
1121 double a99::comma(char *b)
1122 {
1123  // Feld- oder Unterfeldinhalt in Zahl wandeln
1124  // convert b to double, comma -> dot
1125  int i=0;
1126  int d=0;
1127  CHAR *a; a=(CHAR *)b;
1128  CHAR kk[255]; // Hilfsfeld
1129  if(*a=='#') // #nnn oder #uxy
1130  {
1131  a=Rec->AdrSf(a);
1132  if(!a) return 0;
1133  strncpy(kk,a,250);
1134  UtEndSf((char *)kk, Cfg->SF);
1135  a=kk;
1136  } // special cases
1137  else
1138  {
1139  if(*a=='$') { UtRemsp((CHAR *)a); gvar((char *)a+1); a=(CHAR *)zeile; } // $-variable
1140  if(*a=='z') return (double)xiN; // internal counter
1141  if(*a=='Z') return (double)xiZ; // internal number
1142  if(*a==':') return (double)10; // : = symbol for 10, ; for 11 (indexes)
1143  if(*a==';') return (double)11;
1144  }
1145  // in a nach Zahl suchen: erste Ziffer oder -
1146  while(*a && !strchr("0123456789-",*a)) ++a;
1147  while(a[i++])
1148  if(a[i]==',') // Komma = Punkt
1149  { a[i]='.'; break; }
1150  return strtod((char *)a,NULL); // Umwandl in Zahl, dasselbe wie atof(a);
1151 }
1152 
1153 
1154 double a99::eval(char *a)
1155 {
1156  // arithmet. Ausdruck in a auswerten, Zahl zurueck
1157  char t[302]; // fuer einzelne Zahl
1158  int i,j=0; double z=0, T;
1159  char o; o=1; // Operator. 1 = nop (at start)
1160  while(a[j])
1161  {
1162  i=0; // Leerzeichen oder +-*/ trennt die Elemente // vorher strchr("+-/*",a[j])
1163  if(j && a[j]=='-') t[i++]=a[j++]; // Zahl beginnt mit -
1164  while(i<300 && a[j] && !strchr("+-^*/",a[j]))
1165  { t[i++]=a[j++];
1166  if(a[j] && tolower(t[i-1])=='e') t[i++]=a[j++]; // wg. E-n !!!
1167  }
1168  t[i]=0;
1169  switch(o)
1170  {
1171  case '+':
1172  z = z + comma(t); break;
1173  case '-':
1174  z = z - comma(t); break;
1175  case '*':
1176  z = z * comma(t); break;
1177  case '/':
1178  T = comma(t);
1179  if(!T) return 1E300; // Div by zero - return largest possible number
1180  z = z / T; break;
1181  case 1:
1182  z = comma(t);
1183  break;
1184  case '^':
1185  z = pow(z,comma(t));
1186  break;
1187  default: break;
1188  }
1189  while(a[j]==' ') ++j; // next operator, is more's coming
1190  if(a[j] && a[j+1]) { o=a[j]; ++j; while(a[j]==' ') ++j; } else break;
1191  }
1192  return z;
1193 }
1194 
1195 
1196 bool varsave(CHAR *vn, CMapStringToString *uv)
1197 {
1198  // Alle $-Variablen speichern in Datei vn
1199  // FLEX: $0>vn or $1>vn
1200  CString key,text;
1201  POSITION v=NULL;
1202  v=uv->GetStartPosition();
1203  if(!v) return FALSE;
1204  FILE *V=fopen((char *)vn,"w");
1205  if(!V) return FALSE;
1206  while(v)
1207  {
1208  uv->GetNextAssoc(v,key,text);
1209  fprintf(V,"$%s %s\n",LPCTSTR(key),LPCTSTR(text));
1210  }
1211  fclose(V);
1212  return TRUE;
1213 }
1214 
1215 
1217 {
1218  // Menuefunktion "Ansicht/Reg.eintraege" ruft indirekt ShowKeys(1):
1219  ShowKeys(1);
1220 }
1221 
1222 
1223 int a99::Pinst(CHAR *a, int i)
1224 {
1225  // Phrase a einsortieren unter Nr. i
1226  if(UtPinst(a,i)==-1) { MessageBox(Aerror); return -1; }
1227  return 1;
1228 }
1229 
1230 int Findrs(char *rset)
1231 {
1232  // Im Phrasenspeicher einen Erg.Mengennamen finden
1233  int j,k=1; char *b;
1234  while(k<=rss)
1235  {
1236  j=UtPfind(k+3000);
1237  if(j!=-1)
1238  { strncpy(getzeil,(char *)pa[j]+1,200);
1239  if((b=strstr(getzeil," : "))!=0) strcpy(getzeil,b+3); // Name steht hinter " : "
1240  if(!strnicmp(getzeil,rset,strlen(rset))) break; // gefunden!
1241  }
1242  ++k;
1243  }
1244  if(k>rss) return -1;
1245  return k;
1246 }
1247 
1248 
1249 void kalend(char *k)
1250 {
1251  // kalenderdaten (Arbeits- und Freitage, f. aLF
1252  // k ist eine Sequenz von 0 und 1, andere Zeichen dazwischen stoeren nicht
1253  if(!*k) { kal[0]=kp=0; kp0=366; return; } // Bereich loeschen
1254  if(kp==365) kp0=365;
1255  while(*k && kp<10000)
1256  { if(*k=='1') kal[kp++]=1; else if(*k=='0') kal[kp++]=0; ++k; }
1257 }
1258 
1259 
1261 {
1262  // Addr of field k in curr rec, k="#nnn" or "#nn."
1263  // Feld k im aktuellen Satz Rec finden, return Adresse des Feldinhalts (ohne #nnn)
1264  CHAR a[10]; strncpy(a,k,9); a[9]=0; // um k nicht zu aendern
1265  int md=0;
1266  CHAR *b; b=Rec->Adr(a);
1267  int i=strlen(a)-1;
1268  if(!b) b=Rec->Adr(a,++md); // mit md=1 werden auch Untersaetze durchsucht!
1269  if(b) return b;
1270  int o=Cfg->skt;
1271  if(a[i]==':') // a=#nn: bei Mehrfachfeldern: finde das letzte
1272  {
1273  a[i]=0;
1274  int j=Rec->Pos(a,md);
1275  if(j!=-1) { i=Rec->gi[j]; while(i==Rec->gi[++j]); return (Rec->ga[j-1]+o); }
1276  i=strlen(a)-1;
1277  if(a[i]==':') a[i]=0; else return 0;
1278  j=Rec->Pos(a,md); char c;
1279  if(j!=-1) { c=Rec->ga[j][1]; while(c==Rec->ga[++j][1]); return (Rec->ga[j-1]+o); }
1280  return 0;
1281  }
1282  if(a[i]=='.') a[i]=0; else return 0; // a=#nn. ?
1283  i=Rec->Pos(a,md);
1284  if(i!=-1) { if(!i) o+=2; return(Rec->ga[i]+o); }
1285  i=strlen(a)-1;
1286  if(a[i]=='.') a[i]=0; else return 0; // a=#n.. ?
1287  i=Rec->Pos(a,md);
1288  if(i!=-1) { if(!i) o+=2; return(Rec->ga[i]+o); }
1289  else return 0;
1290 }
1291 
1292 
1294 {
1295  // lokale Ersetzung innerhalb iV
1296 
1297  // srch+repl inside iV $$040225 NEW
1298  // a1 start addr of srch term, with *a1 = delimiter
1299  // b1 srch domain
1300 
1301  unsigned int i, j; int m,L,R;
1302  unsigned int k, k1, n, cnt;
1303  unsigned char cmc; /* cmd code : _ or , */
1304  CHAR *retadr; retadr=(CHAR *)NULL;
1305  CHAR *g,*src,*dest; // neu $$981118
1306  CHAR *a, *b;
1307  a=wr; b=b1;
1308  strcpy(a,a1); strcpy(b,b1);
1309  UtRemsp(a);
1310  cmc=*a;
1311  g=b;
1312  if(!*b) return retadr; /* no domain! $$940614 */
1313  i=j=0;
1314  // control code, ^A -> 1 ...
1315  while(a[j]) if(a[j]!='^') a[i++]=a[j++]; // ^~ is for ^ as such
1316  else { a[i]=a[++j]-'@'; if(a[i]==62) a[i]='^'; ++i; ++j; }
1317  a[i]=0;
1318  j=i=strlen(a);
1319  if(j<4 || a[1]==cmc) return retadr;
1320  k=0;
1321  while(j>2) if(a[--j]==cmc) ++k;
1322  j=i;
1323  if(k<2) a[j++]=cmc; // noch cmc anhaengen, wenn nur 1
1324  a[j]=NL;
1325  L=0; while(a[++L]!=cmc); --L;
1326  R=L+2; while(a[R++]!=cmc); R-=(L+3);
1327  i=0; j=strlen(g);
1328  while(i<j)
1329  {
1330  k=1;
1331  while(a[1]!=g[i] && i<j) ++i;
1332  if (++i>j) { i=j; break; } // i = pos behind 1st match in g
1333  n=i;
1334  k1=k;
1335  while(a[++k]!=cmc && (a[k]==g[n])) ++n;
1336 //sprintf(Aerror,"a+k=%s, g+n=%s, k1=%d, l=%d",a+k,g+n,k1,l); MessageBox(Aerror);
1337  if(a[k]==cmc) /* match, repl? */
1338  {
1339  m=i-1; --k; /* m=start pos, k=len of srch str */
1340  src=g+m+k1-1; /* begin shift here */
1341  cnt=(b+strlen(b))-src-L+1; /* this many byte */
1342  dest=g+m+strlen(a)-k-3;
1343 // sprintf(Aerror,"src+L=%s, dest=%s, cnt=%d, m=%d",src+L,dest,cnt,m); MessageBox(Aerror);
1344  if (src+L!=dest)
1345  {
1346  memmove(dest,src+L,cnt);
1347  }
1348  j+=(R-L);
1349  src-=(k1-1);
1350  k+=2;
1351  while (a[k]!=cmc) { *src++=a[k++]; ++i;} /* transfer */
1352  --i;
1353 // sprintf(Aerror,"b=%s,i=%d,g+i=%s",b,i,g+i); MessageBox(Aerror);
1354  }
1355  } /* nxt round */
1356 // strcpy(b1,b);
1357  return retadr;
1358  } // ENDE Repla()
1359 
1360 
1361 
1362 int a99::xcode(char *bx, char *ax,bool mode)
1363 {
1364  // Prepare string for full-text search or xcode ...
1365  // Umcodierung des Satzes oder Feldes mit den div. Tabellen
1366  // srxmode gibt an, welche Tabelle zu nutzen ist FLEX set xab
1367  // ax -> bx lowercase, umlauts etc. mode=1:record, 0:field
1368  int k, m, Gns;
1369  CHAR cx, *u;
1370  char *as, *at;
1371  CHAR cf,cp;
1372  CHAR *ptx, *utx; // p/q table, P/Q table
1373  int pix; // $$000628 NEU 0/1 = p/q
1374  Gns=Bank->Gns;
1375  utx=0;
1376  if(srxmd) // Welche Tabelle?
1377  {
1378  if(srxmd=='d') // set xdp / xcode dp
1379  {
1380  Dsp->xpy=Dsp->rcd=1; Dsp->pix=0; Dsp->ptx=Dsp->ptb[0]; at=(char *)Dsp->ExRcode((CHAR *)ax); strcpy(bx,at); return 0;
1381  // pix=0; ptx=Dsp->ptb[0]; Gns=Dsp->Gns; utx=Dsp->ucp;
1382  } // set xdq
1383  else if(srxmd=='D') // set xdq / xcode dq
1384  {
1385  // pix=1; ptx=Dsp->ptb[1]; Gns=Dsp->Gns; utx=Dsp->ucq;
1386  Dsp->xpy=Dsp->rcd=1; Dsp->pix=1; Dsp->ptx=Dsp->ptb[1]; at=(char *)Dsp->ExRcode((CHAR *)ax); strcpy(bx,at); return 0;
1387  }
1388  else if(srxmd=='i') // set xip / xcode ip
1389  {
1390  Bank->xpy=Bank->rcd=1; Bank->pix=0; Bank->ptx=Bank->ptb[0]; at=(char *)Bank->ExRcode((CHAR *)ax); strcpy(bx,at); return 0;
1391  // pix=0; ptx=Bank->ptb[0]; utx=Bank->ucp;
1392  }
1393  else if(srxmd=='I') // set xiq / xcode iq
1394  {
1395  Bank->xpy=Bank->rcd=1; Bank->pix=1; Bank->ptx=Bank->ptb[1]; at=(char *)Bank->ExRcode((CHAR *)ax); strcpy(bx,at); return 0;
1396  // pix=1; ptx=Bank->ptb[1]; utx=Bank->ucq;
1397  }
1398  else if(Out)
1399  {
1400  Out->ExOutf(noOutput); // echten output verhindern
1401  if(srxmd=='x') // set xxp / xcode xp
1402  {
1403  Out->xpy=Out->rcd=1;
1404  Out->pix=0;
1405  Out->ptx=Out->ptb[0];
1406  at=(char *)Out->ExRcode((CHAR *)ax);
1407  strcpy(bx,at);
1408  Out->ExOutf(putout);
1409  return 0;
1410  // pix=0; ptx=Out->ptb[0]; Gns=Out->Gns; utx=Out->ucp;
1411  }
1412  else if(srxmd=='X') // set xxq / xcode xq
1413  {
1414  Out->xpy=Out->rcd=1; Out->pix=1; Out->ptx=Out->ptb[1]; at=(char *)Out->ExRcode((CHAR *)ax); strcpy(bx,at); Out->ExOutf(putout); return 0;
1415  // pix=1; ptx=Out->ptb[1]; Gns=Out->Gns; utx=Out->ucq;
1416  }
1417  else {strcpy(bx,ax); return 0; }
1418  }
1419  else {strcpy(bx,ax); return 0; }
1420  }
1421  else // no srxmd: use index params
1422  { // set the p/q and P/Q lists to use: those that do A -> a
1423  if(Bank->ptb[0][65]==97) { pix=0; ptx=Bank->ptb[0]; utx=Bank->ucp; }
1424  else { pix=1; ptx=Bank->ptb[1]; utx=Bank->ucq; } // p or q command
1425  }
1426 
1427  cf=ptx[35]; ptx[35]=35; // Damit Suche nach '#' moeglich ist
1428  cp=ptx[46]; ptx[46]=46; // Damit Suche nach '.' moeglich ist
1429  ptx[2]=ptx[3]=ptx[4]=32; // hierarch Untersaetze - sonst wird #01 nicht gefunden
1430 
1431  as=ax; at=bx; // convert as -> at
1432  while(1) /* now eliminate codes 1..3 (non-sort and such) */
1433  {
1434  while(2)
1435  {
1436  cx=*as++;
1437  if(!cx) break;
1438  if(utx && cx>127) // $$030428 NEU Unicode meth 2
1439  {
1440  u=utx;
1441  if(u) while(*u) // UTF-Code in der Liste finden
1442  {
1443  if(*u==cx)
1444  { // > 223: 3-Byte code
1445  if(*++u==*as && (cx<224 || u[1]==as[1]))
1446  { ++as; if(cx>223) ++u,++as; while(*++u) *at++=*u; cx=255; break; }
1447  else while(*++u);
1448  }
1449  else while(*++u); // nxt code
1450  ++u;
1451  }
1452  if(cx==255) continue;
1453  // if(!*u) break; // not found { bx[j++]=cx; bx[j++]=ax[i++]; if(cx>223) bx[j++]=ax[i++]; }
1454  }
1455  else if(ptx[cx]>7) *at++=ptx[cx]; else break; // normal character
1456  }
1457  --as;
1458  while ((cx=*as++)!=NL && ptx[cx]>7) *at++=ptx[cx];
1459  if(cx==NL) if(!mode) { *at=NL; break; } /* exit from while(1) */
1460  else { *at++=0; if(*as==EOD) { *at=EOD; break; } else continue; }
1461  m=0;
1462  switch(ptx[cx])
1463  {
1464  case NL: /* p x 0 : global stop */
1465  *at++=0;
1466  break;
1467  case 1: /* p x 1 : elim x */
1468  break;
1469  case 2: /* p x 2 : elim x and following char */
1470  if(as[1]) ++as; /* $$930818 sonst Absturz, wenn das Zeichen genau
1471  am Ende der Kategorie steht */
1472  break;
1473  case 3: /* p x 3 : same, repl both by ' ' */
1474  if(as[1]) ++as; /* $$930818 sonst Absturz, wenn das Zeichen genau
1475  am Ende der Kategorie steht */
1476  *at++=' ';
1477  break;
1478  case 4: /* p x "abc" : string replacements */
1479  m=0;
1480  if (!pix) k=10000+Gns*300+cx;
1481  else k=20000+Gns*300+cx; /* which tble? */
1482  while (m<phi && pi[m]!=k) ++m;
1483  if (m==phi) break;
1484  k=0;
1485  while ((*at++=pa[m][k++])!=NL) ;
1486  --at; /* the terminating 0 ! */
1487  break;
1488  case 5: /* p x 5 : don't decode this and the following (CHINESE !) */
1489  *at++=cx; if(as[1]) *at++=*++as; /* $$930803 sonst crash */
1490  break;
1491  case 7: /* print ersatz: alt table */
1492  m=1;
1493  case 6: /* print ersatz: normal table */
1494  if(!m) k=10000+cx+300*Gns;
1495  else k=20000+cx+300*Gns; /* which tble? */
1496  m=0;
1497  while (m<phi && pi[m]!=k) ++m;
1498  if (m==phi) break;
1499  k=0;
1500  while ((*at++=pa[m][k++])!=NL);
1501  --at; /* the terminating 0 ! */
1502  break;
1503  default: /* 6 and 7 : print ersatz tables, done at last stage */
1504  *at++=*as;
1505 
1506  break;
1507  }
1508 // ++i;
1509  } /* end while(1) */
1510  ptx[35]=cf; ptx[46]=cp;
1511  return at-bx;
1512 } // ENDE xcode()
1513 
1514 void a99::showIV(char *s,char *t)
1515 {
1516  // s = Modus, '+' : anhaengen
1517  // Inhalt von t in die Anzeige kopieren ( show IV )
1518  int ivl=strlen(t);
1519  if(*s!='+') strcpy(ex,listhead);
1520  else { ++s; /* { */
1521  while(ex[strlen(ex)-1]=='}') ex[strlen(ex)-1]=0; }
1522  if(!strcmp(ex+strlen(ex)-4,"\\par") || !strcmp(ex+strlen(ex)-5,"\\pard")) strcat(ex," "); // u.U. steht \par am Ende
1523  // replace ASCII 20 by 10 = Line feed
1524  if(*s!='B') // show Binary
1525  { char *a; a=t;
1526  while(*a) { if(*a==20 || *a==182) *a=10; ++a; }
1527  strcat(ex,t);
1528  }
1529  else // show IV
1530  {
1531  CHAR *b; b=ex+strlen(ex);
1532  CHAR *a; a=(CHAR *)t;
1533  int n=0;
1534  while(n<ivl)
1535  {
1536  if(*a<32 && *a!=10) { sprintf((char *)b,"{\\cf6 %c}",*a+64); b+=8; }
1537  else { if(strchr("{\\}",*a)) *b++=92; if(*a<255) *b++=*a; else *b++='.'; }
1538  ++a; ++n;
1539  }
1540  *b=0;
1541  } /* {{{ */
1542  strcat(ex,"}}}");
1543  {
1544  rtfpos=0;
1545  m_rdisp.StreamIn(SF_RTF,Rex);
1546  }
1547  m_rdisp.RedrawWindow();
1548 } // ENDE showIV()
1549 
1550 // Vergleichsfunktionen
1551 
1552 int Ascend(const void *Num1,const void *Num2)
1553 {
1554  // compare Num1 and Num2
1555  return( *(long*)Num1 - *(long*)Num2);
1556 }
1557 
1558 int nStrcmp(const void *a1, const void *a2)
1559 {
1560  // compare a1 a2 as strings, descending
1561 return -strcmp( * ( char** ) a1, * ( char** ) a2 );
1562 }
1563 
1564 int Strcmp(const void *a1, const void *a2)
1565 {
1566  // compare a1 a2 as strings, ascending
1567 return strcmp( * ( char** ) a1, * ( char** ) a2 );
1568 }
1569 
1570 // Zeile aus der Datei xf lesen
1571 int readLine(FILE *xf, CHAR *s)
1572 {
1573  // read line from file, line end = 13 or 10 or 13 10
1574  // return 0: EOF
1575  int c; int i=0; CHAR *se;
1576  se=s;
1577  *se=0;
1578  while(1)
1579  { c=fgetc(xf);
1580  if(c==EOF) break;
1581  ++i;
1582  if (c==13 || c==10)
1583  {
1584  while(c==13) c=fgetc(xf); // 13 13 13 10 = one new line
1585  if(c!=10 && c!=EOF) { ungetc(c,xf); c=EOF; } // 13 alone: one new line
1586  break;
1587  }
1588  *se++=(CHAR )c;
1589  if(i>32000) break;
1590  }
1591  *se=0;
1592  return i;
1593 } // ENDE readLine()
1594 
1595 unsigned int readRes2()
1596 {
1597  // read results into result
1598  // Ergebnislistendatei rsF einlesen
1599  unsigned int i=0;
1600  unsigned int r1; signed int rc; long rp;
1601  while(1) // read the result set into result[]
1602  {
1603  rc=fgetc(rsF);
1604  if(rc==EOF) { result[i]=0; return i; }
1605  r1=rc;
1606  rp=(long)r1*16777216L;
1607  r1=fgetc(rsF);
1608  rp=rp+ (long)r1*65536L;
1609  r1=fgetc(rsF);
1610  rp=rp+ (long)r1*256L;
1611  r1=fgetc(rsF);
1612  rp = rp+r1;
1613  result[i]=rp;
1614  ++i;
1615  }
1616 }
1617 
1618 void xmlcod(char *a, char *b)
1619 {
1620  // Hilfsfunktion f. XML-Bearbeitung
1621  // 09 -> <, 11 -> >, 12 -> "
1622  while(*a)
1623  {
1624  if(*a>12) *b++=*a++;
1625  else
1626  { if(*a==9) *b='<';
1627  else if(*a==11) *b='>';
1628  else if(*a==12) *b='"';
1629  else *b=*a;
1630  ++a; ++b;
1631  }
1632  }
1633  *b=0;
1634 }
1635 
1637 {
1638 // Code 8 vorn und hinten vom Schluesseltext beseitigen
1639 // $$980403 remove codes 8 (prim key)
1640  int i=0;
1641  while(ad[i]==8) ++i;
1642  if(i) strcpy(ad,ad+i); // remove 8s from front
1643  i=0;
1644  while(ad[i] && ad[i]!=8) ++i;
1645  ad[i]=0; // put 0 at first 8
1646  Bank->rempunc(ad); // punkt am Ende!
1647 }
1648 
1649 void a99::XMLsub(CHAR *fld)
1650 {
1651  // fld -> w, subfields tagged xml fashion
1652  // Wandlung des Datensatzes in XML mit Beruecks. von Subfields (FLEX xml ...)
1653  CHAR *a, *b; CHAR ns;
1654  a=fld; b=w; CHAR s;
1655  ns=Cfg->NS;
1656  while(*a)
1657  {
1658  if(*a==ns) // non-sort codes -> <ns>...</ns>
1659  {
1660  strcat(w,"\011ns\013");
1661  *a++; b=w+strlen(w);
1662  if(Cfg->nsm) // which non-sort mode? double:
1663  { while(*a && *a!=ns) *b++=*a++; if(*a) *a++;
1664  while(*a && !isalnum(*a) && *a<123 && *a!=ns) *b++=*a++; *b=0;
1665  }
1666  else // single mode:
1667  { while(*a && *a!=' ' && *a!=39) *b++=*a++;
1668  while(*a && !isalnum(*a) && *a<123) *b++=*a++; *b=0;
1669  }
1670  strcat(w,"\011/ns\013"); b=w+strlen(w);
1671  }
1672  else if(*a==Cfg->SF) // subfields $a -> <uf code="a">...</su>
1673  {
1674  *a++; s=*a++;
1675  sprintf((char *)w+strlen(w),"\011uf code=\014%c\014\013%c",(char)s,0); b=w+strlen(w);
1676  while(*a && *a!=Cfg->SF) *b++=*a++;
1677  *b=0; strcat(w,"\011/uf\013"); b=w+strlen(w);
1678  }
1679  else *b++=*a++;
1680  *b=0;
1681  }
1682 return;
1683 } // ENDE XMLsub()
1684 
1685 
1686 void a99::callProg(char *wr, char *cmd)
1687 {
1688  // Externes Prog. starten
1689  // cmd="call" oder "cAll" oder "Call" oder "CAll"
1690  // start external prog
1691 
1692  STARTUPINFO stI;
1693  PROCESS_INFORMATION pI;
1694  ::ZeroMemory(&stI,sizeof(STARTUPINFO));
1695  stI.cb=sizeof(STARTUPINFO);
1696  stI.dwFlags=STARTF_USESHOWWINDOW;
1697  if(cmd[1]=='A') stI.wShowWindow=SW_MINIMIZE;
1698  else stI.wShowWindow=SW_RESTORE;
1699  // BOOL rE=CreateProcess(0,(char *)wr,0,0,FALSE,CREATE_NEW_CONSOLE | CREATE_SEPARATE_WOW_VDM | CREATE_NEW_PROCESS_GROUP,0,0,&stI,&pI);
1700  BOOL rE=CreateProcess(0,(char *)wr,0,0,FALSE,NORMAL_PRIORITY_CLASS,0,0,&stI,&pI);
1701  if(cmd[1]=='A') { SetForegroundWindow(); /* ShowWindow(SW_RESTORE); */ }
1702  UpdateWindow();
1703  if(*cmd!='C')
1704  {
1705 // HANDLE hp[1]; hp[0]=pI.hProcess;
1706  CWaitCursor cc;
1707 // MsgWaitForMultipleObjects(1,hp,TRUE,INFINITE,QS_ALLEVENTS);
1708 // MsgWaitForMultipleObjectsEx(1,hp,INFINITE,QS_ALLEVENTS,MWMO_WAITALL);
1709  WaitForSingleObject(pI.hProcess,INFINITE);
1710  }
1711  CloseHandle(pI.hThread);
1712  CloseHandle(pI.hProcess);
1713 // DWORD lE=GetLastError();
1714  return;
1715 } // ENDE callProg()
1716 
1717 
1719 {
1720  // Wurde Display veraendert? Dann erst fragen, ob gespeichert werden soll
1721  if(accu<5 || m_rdisp.CanUndo()==0) return 0;
1722  int i=MessageBox(uif[411],uif[190],MB_YESNO | MB_ICONQUESTION);
1723  if(i==IDYES) OnM258();
1724  m_rdisp.EmptyUndoBuffer();
1725  return 0;
1726 }
1727 
1729 {
1730  // Formulardatei laden
1731  // und zwar in den Phrasenspeicher ab 25000
1732  FILE *rsF;
1733  rsF=fOpen(frmN,"r",HelpDir);
1734  *Aerror=0;
1735  if(rsF)
1736  { int n=24972+frmn*28; // means we begin at 25000
1737  if(!frmn) // remove old forms if any
1738  {
1739  int m=UtPfind(n);
1740  if(m>0) while(pi[m]>24971 && pi[m]<29999) UtPdel(m);
1741  }
1742  while(fgets(zeile,300,rsF)!=NULL)
1743  {
1744  UtRemsp((CHAR *)zeile); // put all lines to phrase space
1745  if(!*zeile || *zeile==' ') continue;
1746  if(*zeile=='[') { n=24972+frmn*28; frm[frmn]=n; ++frmn; } // form title
1747  Bank->E3Coding((CHAR *)zeile,0,0); // ASCII->ANSI
1748  if(Pinst((CHAR *)zeile,n)==-1) break;
1749  if(frmn>249) { strcpy(Aerror,"Too many forms"); break; }
1750  ++n;
1751  }
1752  fclose(rsF);
1753  if(*Aerror) MessageBox(Aerror);
1754  *Aerror=0;
1755  if(!frmn) m_aform.EnableWindow(FALSE);
1756  }
1757  else return 0;
1758  return 1;
1759 } // ENDE checkDisp()
1760 
1761 int a99::ShowView(char *vn,int md)
1762 {
1763  // ViewListe anzeigen
1764  // show ViewList and select, md==0: open only
1765  // FLEX view 1 name view 1 again view 1 view name
1766  char *wR;
1767  UtRemsp((CHAR *)vn); // trailing spaces
1768  wR=(char *)wr+1;
1769  if(!vn[1] || vn[1]==' ') { *wr=*vn-'0'; if(vn[1]) strcpy(vn,vn+2); else *vn=0; }
1770  else *wr='x';
1771  if(!strncmp(vn,"again",5) || *vn=='?' || !*vn) // view again (same view file as before
1772  {
1773  if(!vwF)
1774  {
1775  vwF=_fsopen(viwN,"r+b",_SH_DENYNO);
1776  // vwn=0;
1777  }
1778  if(!vwF) vwF=fOpen(viwN,"r+b","HELP");
1779  if(!vwF) vwF=fOpen(viwN,"r+b","VIEW");
1780  if(!vwF) return -2;
1781 if(vwn<0) vwn=0;
1782  if(md)
1783  vwn=wkv->DoModal(atF,edF,nwF,vwl,vwz+1,vwn,vwF,Bank,(char *)wr);
1784  else fseek(vwF,0L,0);
1785  }
1786  else
1787  {
1788  strcpy(viwN,vn);
1789  if(vwF) fclose(vwF);
1790 AGAIN:
1791  vwF=_fsopen(viwN,"r+b",_SH_DENYNO);
1792  if(!vwF) vwF=fOpen(viwN,"r+b","VIEW");
1793  if(!vwF) vwF=_fsopen(viwN,"rb",_SH_DENYNO);
1794  if(!vwF) vwF=fOpen(viwN,"rb","VIEW");
1795  if(!vwF) vwF=fOpen(viwN,"rb","HELP");
1796  if(!vwF && !strchr(viwN,'.')) { strcat(viwN,".vw"); goto AGAIN; }
1797  if(!vwF) return -2; // viewfile not found
1798  fgets((char *)wR,250,vwF);
1799  vwl=strlen(wR); wR[vwl-2]=0;
1800  fgets(zeile,250,vwF);
1801  fseek(vwF,0L,2);
1802  vwz=(int)(ftell(vwF)); // Datei leer oder zu klein
1803  if(vwz<6) { MessageBox(uif[140],viwN); fclose(vwF); vwF=0; return -2; } //$$081215
1804  vwz=vwz%vwl;
1805  if(vwl!=strlen(zeile) || vwz>0)
1806  if(!(vwl=viewEql(max(vwl,strlen(zeile)))))
1807  // Diese Datei ist keine ViewListe
1808  { MessageBox(uif[141],viwN); fclose(vwF); vwF=0; return -2; }
1809  else fseek(vwF,0L,2);
1810  vwz=(int)(ftell(vwF))/vwl-1;
1811  if(md)
1812  {
1813  char *ue;
1814  ue=strchr(wR,'|'); if(ue) { ++ue; strcpy(wR,ue); }
1815  vwn=wkv->DoModal(atF,edF,nwF,vwl,vwz+1,1,vwF,Bank,(char *)wr);
1816  }
1817  else { fseek(vwF,0L,0); vwn=0; }
1818  }
1819  if(vwn==-1) return -1;
1820  fseek(vwF,(long)vwn*vwl,0);
1821  fgets(zeile,vwl,vwF);
1822  zeile[vwl-2]=0; // help or flx ?
1823  return vwn;
1824 }
1825 
1827 { nrec=nrec0; m_rset.SetWindowText(uif[396]);
1828 // "Momentan keine Ergebnismenge"
1829 // m_rset.EnableWindow(FALSE);
1830 // m_up.EnableWindow(FALSE); m_down.EnableWindow(FALSE);
1831 // #ifndef ND2 // icon UPU.BMP ...
1832  HBITMAP hb=(HBITMAP) m_bUu.GetSafeHandle();
1833  m_down.SetBitmap(hb);
1834  hb=(HBITMAP) m_bDu.GetSafeHandle();
1835  m_up.SetBitmap(hb);
1836 // #endif
1837  }
1838 
1840 {
1841 // verkn. Saetze zusammenfassen
1842  int j=0, answ=IDNO;
1843  if(*inpu!='|')
1844  {
1845  Bank->Exp(Rec,1,(CHAR *)"@"); // Prim.Schl. ermitteln
1846  code8Remove(Bank->ct[0]);
1847  // Prim.schl. steht jetzt in Bank->ct[0]; '+' suchen
1848  while(Bank->ct[0][j] && Bank->ct[0][j]!='+') ++j;
1849  Bank->ct[0][j]=0;
1850  }
1851  else strcpy(Bank->ct[0],inpu);
1852  j=Bank->InGetSet(Bank->ct[0][1]-'0',(char *)Bank->ct[0]+2,2,1000,result,0,0,'O');
1853  strcpy(zeile,Bank->ct[0]);
1854  if(j>1) answ=IDYES;
1855  anzFam=j;
1856  return answ;
1857 }
1858 
1859 
1861 {
1862 // Index 1 minimieren
1863  if(winxi->GetSafeHwnd() == 0) return;
1864  winxi->ShowWindow(SW_MINIMIZE);
1865  winxi->ShowWindow(SW_HIDE);
1866 // if(fowi!=1) m_list.SetFocus(); // new display if autoflex mode
1867  if(ixon) { --ixon; if(!ixon && !flxflg && afmod) OnDBP("",0,1); }
1868 // if(!ixon) OnDBP();
1869 }
1870 
1872 {
1873 // Index2 minimieren
1874  if(winxj->GetSafeHwnd() == 0) return;
1875  winxj->ShowWindow(SW_MINIMIZE);
1876  winxj->ShowWindow(SW_HIDE);
1877 // if(fowi!=1) m_list.SetFocus();
1878  if(ixon) { --ixon; if(!ixon && !flxflg && afmod) OnDBP("",0,1); }
1879 // if(!ixon) OnDBP();
1880 }
1881 
1882 
1883 void a99::setListFont(BOOL md)
1884 {
1885  // set the font in listbox, md=1: italic
1886  lplf.lfItalic=md;
1887  aFont->CreateFontIndirect(&lplf); // for wkv listing
1888  m_list.SetFont(aFont,TRUE); //test
1889  if(md==TRUE)
1890  { lplf.lfItalic=FALSE; aFont->CreateFontIndirect(&lplf); } // reset for form window!
1891  else lplf.lfItalic=TRUE;
1892 }
1893 
1894 DWORD CALLBACK EditStreamCb(DWORD dwCookie,
1895  LPBYTE pbBuff, LONG cb, LONG FAR *pcb)
1896  {
1897 // String f. RTF vorbereiten: "\par " statt 13 10
1898  int i=0;
1899  char cc;
1900  if(!ex[rtfpos]) return 1;
1901  while((cc=ex[rtfpos]) && i<cb-10) // $$060606 : -10 zur Sicherheit
1902  {
1903  if(cc==13 || cc==10)
1904  { cc=ex[++rtfpos];
1905  if(cc==13 || cc==10) ++rtfpos;
1906  strcpy(pbBuff+i,"\\par "); i+=5;
1907  }
1908  else pbBuff[i++]=ex[rtfpos++];
1909  }
1910  *pcb=(long)i;
1911  return 0;
1912  }
1913 
1914 DWORD CALLBACK SaveStreamCb(DWORD dwCookie,
1915  LPBYTE pbBuff, LONG cb, LONG *pcb)
1916  {
1917  // saving display data
1918  // Anzeige als Text abspeichern
1919 
1920  LONG i=cb; LONG j=0;
1921  char *a=zeile, *b=(char *)pbBuff;
1922  while(i) { if(*b=='\\') if(b[1]=='~') { *a++='`'; b+=2; --i; } else *a++=*b++; else *a++=*b++; --i; ++j; }
1923  // write data to file
1924  // pbBuff=Buffer, cb=Length
1925  // TEST sprintf(Aerror,"%.400s, %ld",(char *)pbBuff,cb); return TRUE;
1926 
1927  if( WriteFile((HANDLE)dwCookie, (LPBYTE *)zeile, j, (unsigned long *)pcb, NULL))
1928  return(FALSE);
1929  else return(TRUE);
1930  }
1931 
1932 int putBuff(int c)
1933 {
1934  // character output function for display window
1935  // c comes out of the export function!
1936  if(ei>4000000) return -1; // RTF LIMIT 4MB
1937  ex[ei++]=(char) c; // simply add char to string ex
1938  return 1; // ex is then sent to display window
1939 }
1940 
1941 int putinpu(int a)
1942 {
1943  // $$100215 output nur in die iV (exp -x)
1944  int i=strlen(inpu);
1945  inpu[i++]=a;
1946  inpu[i]=0;
1947  return i;
1948 }
1949 
1950 int Outnul(int c)
1951 {
1952  // dummy output for index routines: no output
1953  return 1;
1954 }
1955 
1956 
1957 void a99::readSet(FILE *rs)
1958 {
1959  // read a result set number file (.set, erzeugt z.B. von PRESTO)
1960 
1961  CWaitCursor cc; // Sanduhr
1962 
1963  char sn[10];
1964  fgets(srTerm,2999,rs);
1965  int i=0;
1966  while(fgets(sn,10,rs)!=NULL)
1967  {
1968  result[i]=atol(sn);
1969  if(result[i]>0L) ++i; // empty line or no number
1970  }
1971  if(rsF && rsF!=rs1 && rsF!=rs2) fclose(rsF); rsF=0;
1972  if(rss>MXRS) remRset(3); // rem *._3
1973  rsF=openrsF(++rss,"w+b");
1974  fprintf(rsF,"%c%c%c%c",255,255,spos,smod); // flag!
1975  resT=1;
1976  if(i>0) { if(!flxflg && i>1) qsort(&result[0],i,sizeof(RECNR),&UtComplong); } // sort results
1977  else { rsize=0; return; }
1978  int j=0,k=0;
1979  while(j<i) // eliminate dupes
1980  {
1981  while(result[k]==result[j]) ++j;
1982  if(j<i) result[++k]=result[j++];
1983  }
1984  ++k; // ?? if(j>i) --k; // now: k=size
1985  rsize=k;
1986  if(rsize<smax && !flxflg) Bank->InRsort(result,rsize,spos,0,smod); // nummer[] sortieren, max.Laenge
1987 
1988  LONG rp; CHAR a[4];
1989  j=0;
1990  while(j<rsize) // write results to file
1991  {
1992  rp=result[j++];
1993  UtLong2char(rp,a);
1994  // change status to 4 = Online and offset to online Rec#
1995  fprintf(rsF,"%c%c%c%c",a[0],a[1],a[2],a[3]);
1996  }
1997 
1998  UtRemsp((CHAR *)srTerm);
1999  sprintf((char *)w,"%c%4d : (Ext) %s%c",rss,k,srTerm,0);
2000  if(Bank) Bank->E3Coding(w,0,0); // ASCII->ANSI
2001  if(Pinst(w,rss+3000)==-1) MessageBox(Aerror); if(limo==3) OnButton4();
2002  strcpy(srText,w);
2003 
2004  m_rset.SetWindowText((char *)w+1);
2005  m_rset.EnableWindow(TRUE);
2006  m_up.EnableWindow(TRUE); m_down.EnableWindow(TRUE);
2007  fseek(rsF,4L,0);
2008 } // ENDE readSet()
2009 
2010 
2011 int main_ixl(int adn,RECORD *rec, CHAR *adr, int n, int ux4)
2012 {
2013  // zum Nachladen von Saetzen aus Datenbank adn
2014 
2015  if(adn==-1) return 0; // no database available
2016  if(!BANK) return 0;
2017 
2018  if(!Abase[adn]) return 0;
2019 
2020  if(n>199) // switch between databases
2021  {
2022  extern a99 *dlg; // main dialog
2023 // dlg.Check(n);
2024  if(n>200) --n;
2025  if(Active[n-200]==-1) return 0;
2026  rec->Adn=n-200;
2027  return 1;
2028  }
2029 
2030  return ((ABASE *)Abase[adn])->ix_load(rec,adr,n,ux4);
2031 }
2032 
2033 void ixc(int adn, char *ir)
2034 {
2035  // for export variable #ix #uxb, z.B. e5 : Reg. 5 in Index e
2036  extern a99 *dlg; // main dialog
2037  if(!Abase[adn]) *ir='d';
2038  else *ir=((ABASE *)Abase[adn])->aix;
2039  ir[1]=dlg->winxi->ix+'0';
2040  ir[2]=0;
2041 }
2042 
2043 
2044 int main_find(int adn,int ix, CHAR *find, CHAR *found)
2045 {
2046 // find a key in the index, found>=find !
2047  if(adn==-1 || !Abase[adn]) return 0; // no database available
2048 
2049  return aiEntGe(ix,find,found);
2050 }
2051 
2052 void a99::Check(int n)
2053 { //test
2054 // sprintf(Aerror,"n=%d, Adn=%ld, Act=%d",n,Rec->Adn,Active[n-201]);
2055 // MessageBox(Aerror);
2056  return;
2057 }
2058 
2059 
2060 
2061 FILE *a99::openrsF(int i, char *mode)
2062 {
2063  // Aeltere Erg.Menge oeffnen
2064  // open file of result set i
2065  FILE *rf;
2066  strcpy(rssN,rssNB);
2067  sprintf(rssN+strlen(rssN),"._%d%c",i,0); // name._i
2068  rf=fopen(rssN,mode);
2069  if(i>2 && *mode=='w') if(!rf) NoRight(rssN);
2070  if(i>2 && rf) rsx=i;
2071  nrb=1;
2072  return rf;
2073 }
2074 
2075 void a99::NoRight(char *nam)
2076 {
2077  sprintf(Aerror,uif[171],nam); // Datei ... nicht zugaenglich
2078  MessageBox(Aerror,uif[34]); // Dateifehler
2079  exit(10);
2080 }
2081 
2083 {
2084  // read phrase file m.APH // verbessert
2085  // Phrasendaei lesen
2086  int lg;
2087  FILE *fph;
2088  char wx[250];
2089 
2090  Pinst((CHAR *)"¶",20); // Absturzverhuetung bei Strg+t $$070824
2091 // if(!accu) return 0;
2092  if((fph=fopen(phrN,"rt"))==NULL)
2093  if ((fph=fOpen("phrasen","rt"))==NULL) return 0;
2094 
2095 CHAR c20=Bank->etb[0][20]; if(c20==20) Bank->etb[0][20]=32;
2096  while(fgets(wx,250,fph)!=NULL)
2097  {
2098  if(*wx=='#')
2099  { UtRemsp((CHAR *)wx); if(accu>3) UtFinst((CHAR *)wx,2040,Cfg->tgl); continue; }
2100  if(!*wx || *wx==' ') continue;
2101  if(isdigit(*wx)) lg=atoi(wx); else lg=*wx;
2102  if(fgets((char *)w,255,fph)==NULL) break;
2103  UtRemsp(w);
2104  Bank->E3Coding(w,0,0); // srch term ASCII->ANSI
2105  if(Pinst(w,lg)==-1) break;
2106  }
2107 Bank->etb[0][20]=c20;
2108  fclose(fph);
2109  return phi;
2110 } // ENDE aph_read()
2111 
2112 // Phrasen sichern
2114  {
2115 // save phrases to file phrN
2116  FILE *fph;
2117 #ifndef ALCARTA
2118  if(!accu) return;
2119  if(pi[1]>199 || phi<2) return;
2120  if ((fph=fopen(phrN,"wt"))==NULL) return;
2121  else
2122  { int i=0;
2123  while (i<phi)
2124  {
2125  if(pi[i]>255) { ++i; continue; }
2126  if(pi[i]==32 || pi[i]==48) { ++i; continue; }
2127  Bank->E3Coding(pa[i],0,1); // ANSI->ASCII
2128  if(pi[i]<32) fprintf(fph,"%d = ^%c\n%s\n",pi[i],pi[i]+96,pa[i]);
2129  else if(pi[i]<58) fprintf(fph,"%d\n%s\n",pi[i],pa[i]);
2130  else fprintf(fph,"%c\n%s\n",pi[i],pa[i]);
2131  Bank->E3Coding(pa[i],0,0); // ASCII->ANSI
2132  ++i;
2133  }
2134  }
2135  int i;
2136  if((i=fadr((CHAR *)"#uX",3))!=-1)
2137  {
2138  while(fa[i][2]=='X')
2139  { fprintf(fph,"%s\n",fa[i++]); }
2140  }
2141  fclose(fph);
2142 #endif
2143  return;
2144 } // ENDE aph_save()
2145 
2146 
2147 void a99::writelru(RECNR rp, long pos, int rst)
2148 {
2149  // history file (least recently used records)
2150  // save rp to lru file
2151  CHAR a[4];
2152  UtLong2char(rp,a);
2153  HBITMAP hb;
2154  if(pos)
2155  {
2156  fseek(atF,pos,0);
2157  // change status to 4 = Online and offset to online Rec#
2158  fprintf(atF,"%c%c%c%c%c",a[0],a[1],a[2],a[3],rst);
2159  }
2160 
2161  if(rp!=rn2) // don't save the same one twice
2162  {
2163  if (!rs2) // open history file if not open yet
2164  {
2165  rs2=openrsF(2,"r+b");
2166  }
2167  if(!rs2)
2168  {
2169  rs2=fopen(rssN,"w+b");
2170  if(!rs2) NoRight(rssN);
2171  fprintf(rs2,"%c%c%c%c",255,255,spos,4); // flag!
2172  }
2173  fseek(rs2,0L,2);
2174  rn0=(int)(ftell(rs2)/4L);
2175  chgHist(2,rn0);
2176  strcpy(rssN,rssNB);
2177  sprintf(rssN+strlen(rssN),"._%d%c",rsx,0); // restore rssN
2178  m_back.EnableWindow(TRUE);
2179  hb=(HBITMAP) m_fWu.GetSafeHandle();
2180  m_forw.SetBitmap(hb);
2181  hb=(HBITMAP) m_bK.GetSafeHandle();
2182  m_back.SetBitmap(hb);
2183  // save rec# now to res set 2
2184  fprintf(rs2,"%c%c%c%c",a[0],a[1],a[2],a[3]);
2185  fflush(rs2);
2186  rn2=rp;
2187  }
2188 } // ENDE writelru()
2189 
2190 
2192 {
2193  // save rp to bookmark file cat._1
2194  CHAR a[4];
2195  UtLong2char(rp,a);
2196  if(rp!=rn1) // don't save the same one twice
2197  {
2198  if (!rs1) // open bookmark file if not open yet
2199  {
2200  rs1=openrsF(1,"r+b");
2201  }
2202  if(!rs1)
2203  {
2204  rs1=fopen(rssN,"w+b");
2205  if(!rs1) NoRight(rssN);
2206  fprintf(rs1,"%c%c%c%c",255,255,spos,smod,4); // flag!
2207  }
2208 // else if(!svmod) OnM318(); // svmod=1;
2209  fseek(rs1,0L,2);
2210  // save rec# now to res set 1
2211  fprintf(rs1,"%c%c%c%c",a[0],a[1],a[2],a[3]);
2212  {
2213  fflush(rs1);
2214  nbom=ftell(rs1)/4L;
2215  if(nbom) --nbom;
2216  chgHist(1,nbom); // 1 more bookmark
2217  }
2218  rn1=rp;
2219  }
2220 }
2221 
2222 void a99::openForm(int formnr)
2223 {
2224 // Formular mit der lfd. Nr. formnr aufmachen
2225 // (Wenn es zugeht, wird ::OnAform mit Wert 15 aufgerufen, aus aform.cpp)
2226 // if(!fowi || !frmn) return;
2227  if(!frmn) return; // we have no forms
2228  if(limo==1)
2229  {
2230  int ec=m_list.GetCurSel(); // is cursor in a subrecord?
2231  if(ec && ec!=LB_ERR) while(ec && *Rec->ga[ec]!=RS) --ec;
2232 
2233  else ec=0;
2234  Rec->cri=ec;
2235  }
2236  if(limo!=1 || !fowi) OnBackRec();
2237  fomd=1;
2238 
2239  if(m_aDlg->GetSafeHwnd() == 0)
2240  {
2241  m_aDlg->Create(Dsp,Rec,formnr); // nichtmod Editfenster anzeigen
2242  m_aDlg->ShowWindow(SW_RESTORE);
2243  m_aDlg->SetFocus();
2244  }
2245  else if(m_aDlg->IsIconic()) { m_aDlg->ShowWindow(SW_RESTORE); m_aDlg->SetFocus(); }
2246  else { m_aDlg->ShowWindow(SW_MINIMIZE);m_aDlg->ShowWindow(SW_HIDE); }
2247 
2248 }
2249 
2250 void cut(char *ad, char c)
2251 {
2252  // cut ad at first c
2253  char *a=ad;
2254  while(*a) if(*a==c) { *a=0; return; } else ++a;
2255  return;
2256 }
2257 
2258 CHAR* a99::ReadLine(CHAR *pZeile,int ll, FILE *upload, int md)
2259 {
2260  // Zeile aus upload-Datei lesen
2261  // read 1 line from upload file
2262  // md=0: ASCII file 1: .ALG file
2263  // return 0, wenn Dateiende
2264 
2265  int i=0; int c;
2266  if(!upload) { if(getCmd((CHAR *)zeile)) return (CHAR *)zeile; else return 0; }
2267 
2268  // text file
2269  if(!md) return (CHAR *)fgets((char*)zeile,ll,upload);
2270 
2271  // ALG file
2272  c=fgetc(upload);
2273  while(c==13 || c==10 || !c) c=fgetc(upload);
2274  if(c==EOF) return 0;
2275  if(c<10) c=fgetc(upload); // new rec or subrec begins!
2276  zeile[i++]='#'; // '#' at first position
2277  while(i<ll)
2278  {
2279  zeile[i++]=c;
2280  c=fgetc(upload);
2281  if(c<1) { zeile[i]=0; return (CHAR *)zeile; }
2282  }
2283  return 0;
2284 } // ENDE ReadLine()
2285 
2286 
2287 #ifdef A99
2288 
2289 // Nur in a99 FLEX: upload-Daten einlesen
2290 #define EOZ 92
2291 
2292 int a99::getCmd(CHAR* pCmd)
2293 {
2294  // naechste Befehlszeile aus jobstore holen
2295  // d.h. Zeile von Pos. jp bis zum naechsten
2296  // return: 1=ok, 0=Ende
2297  CHAR* ptr;
2298  long lLen=0L;
2299 
2300  if(*jp==0 || (ptr=(CHAR*)strchr(jp,EOZ))==(CHAR*)NULL) return 0;
2301 // ptr zeigt auf naechsten EOZ
2302  else lLen=(char *)ptr-jp;
2303  memset((char *)pCmd,0,lLen+1);
2304  memcpy((char *)pCmd,jp,lLen);
2305  jp=(char *)ptr+1;
2306  return 1;
2307 }
2308 
2309 // nicht in alcarta:
2310 
2311 int a99::RRec(RECORD *Satz, int md)
2312 {
2313  // Satz aus UPLOAD einlesen (wird vorher geoeffnet)
2314  // md == 0: ASCII file
2315  // 1: .ALG file
2316  // in Satz kann schon was stehen; Kategorien werden durch die neu
2317  // eingelesenen ersetzt, wenn md==0
2318 
2319  int rc; int p;
2320  int nwr=0; // 1: new rec is beginning (.ALG)
2321  int rflag=0; // real flag: 1 after first real field found (>= #00)
2322  RECNR posit; // offset position in file, for nxt rec
2323  p=Cfg->skt;
2324  *Aerror=0;
2325  {
2326  // $$970111 Aenderung: !upload = Daten sind in FLEX eingebettet
2327  if(ReadLine((CHAR *)zeile,30000,upload,md)!=0)
2328  {
2329  UtRemsp((CHAR *)zeile); // CR/LF und Leerz. am Ende beseitigen
2330  // codes umwandeln, wenn dx=1 gesetzt, d.h. o-Tabelle anwenden:
2331 // if(codflag) Bank->E3Coding((CHAR *)zeile,0,1);
2332  strcpy(inpu,zeile);
2333  while(1)
2334  {
2335  if(upload) posit=ftell(upload); else posit=jp-jobstore; // $$970111 NEU
2336  if(md) // .alg : check nxt char, is it 1, 8 or 9?
2337  {
2338  rc=fgetc(upload); // there may be 13, 10, or additional 0
2339  while(rc==13 || rc==10 || !rc) rc=fgetc(upload);
2340  if(rc==1 || rc==8 || rc==9) { rc=fgetc(upload); nwr=1; } // naechster Satz kommt
2341  else nwr=0;
2342  ungetc(rc,upload);
2343  }
2344  if(ReadLine((CHAR *)zeile,30000,upload,md)==0) // ENDE der Datei
2345  {
2346  if(*inpu=='#')
2347  {
2348  if(inpu[p]=='_' && !inpu[p+1]) strcat(inpu," ");
2349  if(inpu[Cfg->skt]=='~') inpu[Cfg->skt]=')'; // #nnn ~text -> )text
2350  *Aerror=9;
2351  if(cmod=='1') Bank->E3Coding((CHAR *)inpu,0,1); // ANSI->ASCII wenn set c1
2352  Satz->Ins((CHAR *)inpu); *Aerror=0;
2353  }
2354  sprintf(Aerror,"* File end%c",0);
2355  break;
2356  }
2357  UtRemsp((CHAR *)zeile);
2358  if(zeile[1]==10) strcpy(zeile+1,zeile+3); //$$970204 NEU
2359  if(!*zeile) // continue; // leere Zeile ignorieren - nein, neuer Satz beginnt
2360  {
2361 // if(upload) fseek(upload,posit,0); // reposition read pointer
2362 // else jp=jobstore+posit; // $$970111 NEU
2363  if(*inpu=='#') // Es steht noch was in iV, verarbeiten!
2364  {
2365  if(inpu[p]=='_' && !inpu[p+1]) strcat(inpu," ");
2366  if(inpu[Cfg->skt]=='~') inpu[Cfg->skt]=')'; // #nnn ~text -> )text
2367  *Aerror=9;
2368  if(cmod=='1') Bank->E3Coding((CHAR *)inpu,0,1); // ANSI->ASCII wenn set c1
2369  Satz->Ins((CHAR *)inpu); *Aerror=0;
2370  }
2371  break; // while(1) Satz zu Ende
2372  }
2373 // if(codflag) Bank->E3Coding((CHAR *)zeile,0,1);
2374  if(*zeile=='#') // naechste Kategorie wurde gelesen
2375  {
2376  if(*inpu=='#') // steht was in inpu? (voriges Feld!)
2377  {
2378  rc=Cfg->KoVerify((CHAR *)inpu);
2379  if(rc==-1) continue; // not a valid field or ###
2380  if(rc>3 && rc<8) // is it a subrecord?
2381  {
2382  rc=Satz->SubPos((CHAR *)inpu); // find subrec
2383  if(rc==-1) Satz->cri=Satz->gri; // not found: new subrec
2384  }
2385  if(inpu[p]=='_' && !inpu[p+1]) strcat(inpu," ");
2386  if(inpu[Cfg->skt]=='~') inpu[Cfg->skt]=')'; // #nnn ~text -> )text
2387  if(cmod=='1') Bank->E3Coding((CHAR *)inpu,0,1); // ANSI->ASCII wenn set c1
2388  *Aerror=9; Satz->Ins((CHAR *)inpu); *Aerror=0;
2389  }
2390  strcpy(inpu,zeile); // inpu ist jetzt Anfang der naechsten kat.
2391  rc=Cfg->KoVerify((CHAR *)inpu); // rc = CFG number of field
2392  if(nwr || (rflag && rc>0 && rc<4))
2393  // #00, #u1 #u2 : neuer Satz beginnt
2394  { // aber nur, wenn rflag>0
2395  if(upload) fseek(upload,posit,0); // reposition read pointer
2396  else jp=jobstore+posit; // $$970111 NEU
2397  break; // while(1)
2398  }
2399  else if(rc>2) rflag=1; // 1st real field found
2400  }
2401  else if(*zeile!=' ') // Wenn eine Zeile nicht mit '#' oder Leer beginnt,
2402  { // endet das Einlesen!!!
2403  if(*inpu=='#')
2404  {
2405  if(inpu[p]=='_' && !inpu[p+1]) strcat(inpu," ");
2406  if(cmod=='1') Bank->E3Coding((CHAR *)inpu,0,1); // ANSI->ASCII wenn set c1
2407  *Aerror=9; Satz->Ins((CHAR *)inpu); *Aerror=0; // Satz speichern
2408  }
2409  sprintf(Aerror,"Wrong line: %s%c",zeile);
2410  break; // out of while(1)
2411  }
2412  else strcat(inpu,zeile); // ==' ' : es war eine Forts. Zeile; anhaengen
2413  } // end while(1)
2414 
2415  Satz->cri=0;
2416  }
2417  else
2418  {
2419  sprintf(Aerror,"*End%c",0);
2420  }
2421  rc=Satz->gri; // number of fields
2422  if(rc<1) sprintf(Aerror," End of file%c",0);
2423  }
2424  if(Satz->Adn==-1) Satz->Adn=0; //$$970204 NEU
2425  // Zugehoerigkeit zur Datenbank 0
2426  return rc;
2427 } // ENDE RRec()
2428 
2429 #else // alcarte
2430 int a99::getCmd(CHAR* pCmd) // naechste Befehlszeile aus jobstore holen
2431 { return 0; }
2432 #endif
2433 
2434 // ----------------------------------------------------
2435 // FLEXecute()
2436 // ************* FLEX-Interpreter *********************
2437 // ----------------------------------------------------
2438 
2439 // these need to be global because of repeated calls to FLEXecute()
2440 int kai, zai; // auxil
2441 int ivl; // length of internal var
2442 char cmd[8000]; // current command
2443 char C; // cmd symbol
2444 char rgx[2008]; // last regex from cmd srx
2445 RECNR irn, mrn; // internal recn of curr rec / max rec#
2446 long fsz; // size of "open" file
2447 int qmo; // qrix mode
2448 int ifm; // if mode, ifm==1: ; is separator!
2449 int pctr; // progr counter
2450 double iZ; // interne Zahl
2451 long iN; // interne Nummer
2452 EXET *OUt; // auxil ptr
2453 FILE *xF; // for FLEX: open / read #
2454 int yex; // y==IDNO: cancel FLEX
2455 int iex; // Position beim Parsen einer FLEX-Zeile
2456 int jex; // Pos. des Befehlsbeginns derselben Zeile
2457 
2458 
2459 int a99::FLEXecute(char *xcmd)
2460 {
2461  // Der FLEX-Interpreter
2462  // execute xcmd (FLEX)
2463  // xcmd = "x commands" or "X filename"
2464  // return: 0 = OK, 1: repeat, -1: file not found
2465 
2466  int fow=fowi; // focus window
2467  char wlab[2]; // wri label : Sprungmarke fuer write-Befehl
2468 // int j;
2469 
2470  *wlab=0;
2471 // wenn xcmd=="", wird der vorher laufende FLEX wieder aufgenommen
2472  if(*xcmd) { kai=-1; zai=ivl=qmo=ifm=0; irn=mrn=fsz=0; pctr=100; }
2473  // char cmod='0'; // e.adt is 0=ASCII 1=ANSI
2474 // if(!fowi) return 0; // not initialized
2475  if(*xcmd && flxflg) return 0; // a FLEX is still running
2476 // m_list.SetFocus();
2477  if(!*xcmd && flxflg) ; // continue the interrupted FLEX
2478  else if(*xcmd=='x')
2479  { strcpy(jobstore,xcmd+2); xc=jobstore; iN=iZ=0; xF=0; answ=-2; subi=0; *flxnm=0;
2480  uva.RemoveAll(); va=NULL;
2481  kai=-1; zai=0; // auxil
2482  }
2483  // "x chain" -> "chain"
2484  else if(*xcmd=='X') // X : read FLEX from file
2485  {
2486  int i;
2487  FILE *cf, *cf1; cf1=NULL;
2488  iN=iZ=0; xF=0; subi=0;
2489  answ=-2;
2490  Vmod=0;
2491  *jobstore=0;
2492  i=1;
2493  while(xcmd[i]==' ') ++i;
2494  strcpy(cmd,xcmd+i); // X flexname argument, argument -> iV
2495  i=0;
2496  {char *a; a=strchr(cmd,' '); if(a) { *a=0; strcpy(inpu,a+1); } else *inpu=0; }
2497  if(!strchr(cmd,'.')) strcat(cmd,".flx"); // add .flx to name
2498  if(accu>4) sprintf(flxnm," [%s]",cmd); // FLEX name
2499  cf=fOpen(cmd,"r",FlexDir);
2500  if(!cf && *cmd=='_') cf=fOpen(cmd+1,"r",FlexDir);
2501  if(!cf) return -1; // file not found
2502 // flxflg=1;
2503  char c; char *ap;
2504 // Datei einlesen
2505 JOBREAD:
2506  while(strlen(jobstore)<255900 && fgets((char *)wr,3000,cf)!=NULL)
2507  {
2508  UtRemsp(wr);
2509  if(!*wr || isspace(*wr) || (*wr=='/' && wr[1]=='/')) continue; // empty or comment
2510 // Bank->E3Coding((CHAR *)wr,0,0);
2511  ap=(char *)wr+1;
2512  if(*wr!='#' && *wr!='$' && *wr!=31) // keine Datenzeile?
2513  while(*ap) // dann Kommentar bei // abschneiden
2514  {
2515  if(*ap==39 || *ap==34)
2516  { c=*ap++; while(*ap && *ap!=c) ++ap; if(*ap) ++ap; else break; }
2517  if(*ap==' ' && ap[1]=='/' && ap[2]=='/') { *ap=0; UtRemsp(wr); break; }
2518  else ++ap;
2519  }
2520 if(!strncmp(wr,"include ",8) && !cf1) // include filename
2521 {
2522  cf1=cf; cf=fOpen((char *)wr+8,"r",FlexDir);
2523  if(!cf) { cf=cf1; cf1=NULL; /* MessageBox((char *)wr+8,"Datei nicht gefunden"); */} // klappte nicht
2524  continue;
2525 }
2526  if(*jobstore && *wr!='|') strcat(jobstore,"\\"); // select!
2527  strcat(jobstore,wr);
2528  }
2529  if(strlen(jobstore)>255000) { sprintf(Aerror,"FLEX %s too big",xcmd); MessageBox(Aerror); }
2530  if(cf1) { fclose(cf); cf=cf1; cf1=NULL; goto JOBREAD; } // include zu Ende
2531  xc=jobstore;
2532  fclose(cf);
2533  uva.RemoveAll(); va=NULL;
2534  kai=-1; zai=0; // auxil
2535  }
2536  else
2537  { strcpy(jobstore,xcmd); xc=jobstore; xF=0; uva.RemoveAll(); va=NULL; kai=-1; zai=0; // auxil
2538  } // now: xc = FLEX string,
2539  // chain of commands, \-delimited
2540  m_rdisp.EmptyUndoBuffer(); // damit keine Frage kommt
2541  strcat(jobstore,"\\\1"); // if last line was :label!
2542  *Aerror=0;
2543  irn=Rec->rNr;
2544 fF=1; // flag for timerflex
2545 
2546  // ------------------------------------------------------------------
2547  // Job beginnt bei Adresse xc, Hauptschleife zur Abarbeitung des FLEX
2548  // ------------------------------------------------------------------
2549  while(*xc) // pointer xc always shifts to the next cmd line
2550  {
2551  // Anfang auf das erste richtige Zeichen setzen
2552  while(isspace(*xc) || *xc=='\\') ++xc; // strcpy(xc,xc+1);
2553  iex=jex=0;
2554 
2555  // VORBEARBEITUNG: commands werden durch 1 Byte Codes ersetzt!
2556  // d.h. Zeichen auf *xc wird ersetzt.
2557  // Tip: Suche nach Befehl "addform": steht bei "case 24"
2558  // !!! LEIDER ganz anders als in acon !!!
2559  // Wenn hier kein Code gesetzt wird, gilt der Anfangsbuchstabe, z.B. bei if ...
2560  // Achtung: 12 und 13 meiden, die gehen dabei nicht
2561 C=*xc; // f. Befehl "flow"
2562  switch(*xc)
2563  { // Code Befehl
2564  case 'a':
2565  if(xc[1]=='c') *xc=96; // activate
2566  else if(xc[2]=='k') *xc='@'; // ask
2567  else if(xc[1]=='d') *xc=24; // addform
2568  else if(xc[1]=='r') *xc='['; // aresqa
2569  break;
2570  case 'c':
2571  if(xc[1]=='a') *xc='ä'; // call
2572  else if(xc[1]=='A') *xc='ä'; // cAll
2573  else if(xc[1]=='h') *xc=3; // choose
2574  else if(xc[1]=='l') *xc=14; // close
2575  else if(xc[1]=='r') *xc=15; // crypt
2576  else if(xc[1]=='c') *xc=94; // ccopy (Clipboard copy)
2577  else if(xc[1]=='p') *xc=93; // cpaste (Clipboard paste)
2578  break;
2579  case 'D':
2580  if(xc[2]=='y') *xc=124; // Day
2581  if(xc[2]!='w' && tolower(xc[1])=='o')
2582  *xc=29; // Dos
2583  break;
2584  case 'd':
2585  if(xc[2]=='l') *xc='6'; // delete
2586  else if(xc[2]=='y') *xc=123; // day
2587  else if(xc[1]=='a') *xc='T'; // date = Timestamp
2588  else if(xc[2]=='r') *xc='ó'; // dir
2589  else if(xc[1]=='i') *xc=7; // display
2590  else if(xc[1]=='e') *xc=8; // deposit
2591  else if(xc[1]=='o' && (xc[2]=='s' || xc[2]==' ')) *xc=28; // dos
2592  break;
2593  case 'E':
2594  if(xc[1]=='x') *xc='D'; // Export = Download
2595  break;
2596  case 'e':
2597  if(xc[1]=='n') *xc=1; // end
2598  if(xc[1]=='v') *xc='û'; // eval
2599  if(xc[2]=='e') *xc=22; // exec
2600  if(xc[2]=='p') *xc='d'; // export = download
2601  break;
2602  case 'f':
2603  if(xc[1]=='o') *xc=4; // form
2604  else if(xc[2]=='l') *xc=25; // file
2605  else if(xc[2]=='r') *xc=21; // first
2606  else if(xc[1]=='e') *xc='3'; // fetch
2607  else if(xc[2]=='e') *xc='7'; // flex
2608  else if(xc[1]=='n') *xc='1'; // fnam
2609  else if(xc[1]=='c') *xc='K'; // fcopy
2610  else if(xc[1]=='s') *xc='%'; // fsize
2611  else if(xc[1]=='t') *xc='Y'; // ftime
2612  else if(xc[1]=='l')
2613  if(xc[2]=='o') *xc='³'; // flow
2614  else *xc='4'; // flip
2615  else if(xc[1]=='1') *xc='î'; // f1nd
2616  else if(xc[1]=='a') *xc=19; // family
2617  break;
2618  case 'i':
2619  if(xc[2]=='s') *xc='ö'; // insert z
2620  else if(xc[2]=='p') *xc=125; // input I
2621  else if(xc[1]=='x') *xc='ù'; // ixadd / ixdel
2622  else if(xc[2]=='d') *xc='ò'; // index
2623  break;
2624  case 'j':
2625  if(xc[1]=='a') *xc=41; // janas
2626  break;
2627  case 'l':
2628  if(xc[1]=='a') *xc=20; // last
2629  break;
2630  case 'm':
2631  if(xc[2]=='n') *xc='G'; // menu
2632  if(xc[1]=='k') *xc=30; // mkdir
2633  break;
2634  case 'n':
2635  if(xc[1]=='o') *xc='N'; // noyes N
2636  else if(xc[2]=='x') *xc=5; // next
2637  else if(xc[1]=='x') *xc=5; // nxt
2638  break;
2639  case 'o':
2640  if(xc[1]=='p') *xc='O'; // open
2641  break;
2642  case 'p':
2643  if(xc[1]==' ') break; // p x abc ABC
2644  else if(xc[2]=='e') *xc=6; // previous
2645  else if(xc[1]=='r') *xc=23; // print
2646  else if(xc[1]=='h') *xc='è'; // phrase
2647  else if(xc[2]=='r') *xc=18; // perform
2648  else if(xc[1]=='i') *xc='ì'; // pipe
2649  break;
2650  case 'r':
2651  if(xc[2]=='p') *xc=11; // repeat
2652  else if(xc[2]=='n') *xc='5'; // rename
2653  else if(xc[2]=='t') *xc=17; // return (from subrout)
2654  break;
2655  case 's':
2656  if(xc[1]=='l') *xc='é'; // sleep/slice S
2657  else if(xc[1]=='r') *xc='â'; // srx (regex)
2658  else if(xc[2]=='l') *xc=2; // select
2659  else if(xc[1]=='h') *xc='8'; // show
2660  else if(xc[1]=='p') *xc=16; // spaces
2661  else if(xc[1]=='a') *xc=10; // save
2662  else if(xc[1]=='u') *xc='('; // sub
2663  else if(xc[1]=='o') *xc='ú'; // sort
2664  break;
2665  case 'S':
2666  if(xc[1]=='T') *xc=27; // STOP
2667  break;
2668  case 'u':
2669  if(xc[1]=='n') *xc='U'; // undo
2670  else if(xc[2]=='l') *xc='L'; // upload
2671  break;
2672  case 'v':
2673  if(xc[1]=='i') *xc=26; // view
2674  break;
2675  case 'x':
2676  if(xc[1]=='c') *xc='ê'; // xcode/xchange iq/p xq/p dq/p, _A_B_, *nn_a_b_
2677  else if(xc[1]=='p') *xc='d'; // xport = download
2678  break; // bleibt uebrig: xml
2679  case 'z':
2680  *xc='!'; // zaehler
2681  break;
2682  case 'Z': // Z+-X/ : Rechenbefehle fuer iZ
2683  ++xc; while(*xc==' ') ++xc; if(*xc=='*') *xc='X';
2684  break;
2685  case 'W': *xc=127; // Wday
2686  break;
2687  case 'A': // ASCI / ANSI / Aresqa
2688  if(xc[1]!='r') *xc='a'; else *xc='<';
2689  break;
2690  /*
2691  case 'C':
2692  case 'F':
2693  case 'I':
2694  case 'P':
2695  case 'V':
2696  case 'g':
2697  case 'h':
2698  case 'j':
2699  case 'k':
2700  case 'q':
2701  case 't':
2702  case 'w':
2703  case 'x':
2704  case 'y':
2705  case 'z':
2706  case ':':
2707  case '-':
2708  case '+':
2709  case 'X':
2710  case '/':
2711  case '#':
2712  case '*':
2713  case '$':
2714  case '_':
2715  case '?':
2716  case '=':
2717  case ' ':
2718  case '\\':
2719  case 0:
2720  case 1:
2721  case 9:
2722  break;
2723 */
2724  default:
2725 // MessageBox(xc,"ERROR: Wrong command");
2726 // if(isdigit(*xc)) *xc=' ';
2727  break;
2728  }
2729 
2730  while(1) // set xc to next cmd (after next \ )
2731  {
2732  if(ifm) // if-mode: look for ;
2733  {char c;
2734  while(xc[jex]) // 0 is end of FLEX
2735  {
2736  if(xc[jex]==39 || xc[jex]==34) // quotes
2737  { c=cmd[iex++]=xc[jex++];
2738  while(xc[jex] && xc[jex]!=c)
2739  { cmd[iex++]=xc[jex++]; if(cmd[iex-1]=='\\' && xc[jex]=='\\') ++jex; }
2740  }
2741  if(!xc[jex]) break; // end of job
2742  if(xc[jex]=='\\') if(xc[jex+1]!='\\') { ifm=2; break; } // nxt normal cmd reached
2743  else ++jex;
2744  if((cmd[iex]=xc[jex])!=';') ++iex,++jex; /* ; is end of cmd */
2745  else break;
2746  }
2747  }
2748  if(!ifm)
2749  {
2750  while(xc[jex] && (cmd[iex]=xc[jex])!='\\') ++iex,++jex; /* \\ -> \ */
2751  if(xc[jex]=='\\' && xc[jex+1]=='\\') { jex+=2; ++iex; continue; } else break;
2752  }
2753  else if(ifm==2) ifm=0;
2754  break;
2755  }
2756  cmd[iex]=0; if(!iex) break;
2757  if(xc[jex]) { xc+=jex+1; while(*xc==' ') ++xc; } else xc+=jex; // xc = naechster Befehl
2758 if(Vmod==2)
2759 { sprintf(getzeil,"\n%c%s : %.50s\n",C,cmd+1,inpu);
2760  showIV("+I",getzeil);
2761 }
2762 
2763  yex=IDYES;
2764  iex=1;
2765  if(!strchr("=+-X/?~*_!",*cmd)) // one-symbol commands!
2766  while(cmd[iex] && cmd[iex]!=' ') ++iex;
2767 
2768  while(cmd[iex]==' ') ++iex;
2769  if(*cmd==13) *cmd='?'; // 'index' same as ?
2770 
2771 
2772  // ----------------------------
2773  // Abarbeitung einer FLEX-Zeile
2774  // ----------------------------
2775  switch(*cmd) // *cmd = FLEX command code
2776  // and command argument is now at cmd+i
2777  {
2778  case ':': // label
2779  break; // do nthg
2780  case 'â': // srx : regex search
2781  {
2782  char *p; p=cmd+iex;
2783  answ=IDNO;
2784  if(cmd[2]!='X') // srX : repeat last srx, is still in regex class!
2785  {
2786  if(!*p)
2787  { p=(char *)UtFind("#u!!"); // Term in #u!! if not in cmd line
2788  if(!p) { answ=IDCANCEL; break; } else p+=Cfg->skt;
2789  }
2790  strcpy(rgx,p); p=rgx;
2791  Repla((CHAR *)"_ + _\037\037+_",(CHAR *)p); // + AND jeweils 2xCode31 davor
2792  Repla((CHAR *)"_ / _\037\037/_",(CHAR *)p); // / OR
2793  Repla((CHAR *)"_ - _\037\037-_",(CHAR *)p); // - NOT
2794  Repla((CHAR *)"_ % _\037\037%_",(CHAR *)p); // % EXOR
2795  p = re_comp(p); // if p!=0 error!
2796  if(p) { strcpy(inpu,p); answ=IDCANCEL; break; } // p = error msg
2797  // p==0: ok
2798  }
2799  xcode((char *)ex,(char *)inpu,0);
2800  if(re_exec((char *)ex)) answ=IDYES;
2801  }
2802  break;
2803  case '3': // fetch bytes from xF into iV
2804  {
2805  int mo=0; // mo==1: read as is, 0: replace ctrl codes by ^codes
2806  int md=cmd[iex];
2807  unsigned int c,d;
2808  int K=-1; // fuer Modus fetch ^code
2809  if(!xF && Fty!=2) { strcpy(inpu,"-1"); answ=IDCANCEL; break; }
2810  if(md=='+') md=cmd[++iex]; // +: an iV anhaengen
2811  else { if(md!='m' && md!='e') *inpu=0; ivl=0; }
2812  if(md=='r') // fetch r : complete record
2813  { // pointer must be on 1st byte of rec, not on code 1 or recnr
2814 
2815  c=1; *inpu='#';
2816  if(fgets((char *)ex,65000,xF)!=NULL)
2817  {
2818  char *e, *i; e=(char *)ex, i=(char *)inpu; ++i;
2819 // am Ende von ex steht 13 oder 10, meistens beides
2820  while(*e!=13 && *e!=10)
2821  {
2822  if(!*e) { *i++=10; *e='#'; } // 0 ersetzen durch LF #
2823  else if(*e<8) { ++e; continue; } // hierarch subrec
2824  *i++=*e++;
2825  }
2826  i[-2]=0; // 0 ans Ende
2827  }
2828  else c=EOF;
2829 
2830 if(!pctr)
2831 { sprintf(Aerror+1000,"%d %c",(int)(((double)100*(double)ftell(xF))/(double)fsz),37);
2832  pctr=100;
2833  m_status.SetWindowText(Aerror+1000);
2834 }
2835 else --pctr;
2836 
2837 // counter(ftell(xF),fsz); // Fortschr.anzeige = Position in Datei
2838 
2839  if(c==EOF) answ=IDCANCEL; else answ=IDYES;
2840  break;
2841  }
2842 
2843  if(md=='T') { mo=1; md=cmd[++iex]; } // fetch T : text mode
2844  if(md=='A') { mo=2; md=cmd[++iex]; } // fetch A : allegro mode
2845  yex=answ=IDYES;
2846  if(!xF && Fty!=2) { answ=IDNO; break; }
2847 
2848  if(md=='p') // fetch pos = write offset pos to iV
2849  { sprintf(inpu,"%ld",ftell(xF));
2850  break;
2851  }
2852  if(md=='m') // fetch mov = move to offset pos
2853  {
2854  fseek(xF,atol(inpu),SEEK_SET); // value undefined!
2855  break;
2856  }
2857  if(md=='c' || md=='b') // fetch c : nxt byte -> inpu, no advance
2858  {
2859  jex=fgetc(xF); sprintf(inpu,"%d",jex);
2860  if(jex!=EOF) { if(md=='c') ungetc(jex,xF); }
2861  else { strcpy(inpu,"-1"); answ=IDCANCEL; break; }
2862  if(md=='c' || !cmd[iex+1]) break; // nur c oder b
2863  long h=(long)jex*256L; // b4
2864  if(cmd[iex+1]>'3') h=(h+(long)fgetc(xF))*256L; // b3
2865  if(cmd[iex+1]>'2') h=(h+(long)fgetc(xF))*256L; // b3
2866  h=h+(long)fgetc(xF); // b2
2867  sprintf(inpu,"%ld",h);
2868  break;
2869  }
2870  if(md=='e') // fetch en : iV contains en bytes of ctrl chars = end sequence
2871  { int n=atoi(cmd+iex+1); if(!n) n=strlen(inpu); if(!n) n=1;
2872  if(get_text(xF,(CHAR *)inpu,n,(CHAR *)inpu)) { answ=IDNO; break; }
2873  if(*Aerror=='-') answ=IDCANCEL; // inpu not found!
2874 // else if(itrans(inpu,ex,strlen(inpu))) strcpy(inpu,ex);
2875  break;
2876  }
2877 // fetch number
2878  jex=strlen(inpu);
2879  int n=atoi(cmd+iex);
2880  if(!n) if(cmd[iex]=='^') { K=atoi(cmd+iex+1); if(!K) K=cmd[iex+1]-64; } else n=100;
2881  if(Fty==2) // Internetfile
2882  {
2883  n=InterRead(n); if(n<1) answ=IDCANCEL;
2884  break;
2885  }
2886  while(K>-1 || n--)
2887  { d=c=fgetc(xF); if(c==EOF) break;
2888  if(mo) ;
2889  else if(c<32) { inpu[ivl++]='^'; c+=64; } // Ctrl codes -> ^A ...
2890  else if(c=='^') { inpu[ivl++]='^'; c='~'; } // ^ -> ^~
2891  if(mo==1) { if(c!=13 && c!=10) inpu[ivl++]=c; }
2892  else if(mo==2) { if(c>10 && !strchr("\r\x1a\x1b",c)) inpu[ivl++]=c; }
2893  else inpu[ivl++]=c;
2894  if(d==K || ivl>255998) break; // max 8K
2895  }
2896  inpu[ivl]=0;
2897  if(c!=EOF) counter(ftell(xF),fsz);
2898  else { answ=IDCANCEL; counter(0,100); }
2899  }
2900  break;
2901 
2902  case 18: // perform subrout
2903  subi=xc;
2904  case 'j': // jump to label
2905  {
2906  if(!cmd[iex]) strcpy(cmd+iex,inpu); // dynamische Spruenge! label in iV
2907 if(Vmod==1)
2908 {
2909  if(*cmd==18) sprintf(getzeil,"perf %s : %.50s\n",cmd+iex,inpu);
2910  else sprintf(getzeil,"jump %s : %.50s\n",cmd+iex,inpu);
2911  showIV("+I",getzeil);
2912 }
2913  xc=jobstore;
2914  while(1)
2915  {
2916  if(*xc==':')
2917  if(!strncmp(xc+1,cmd+iex,strlen(cmd+iex)) && xc[1+strlen(cmd+iex)]=='\\') break;
2918  while(*xc && *xc!='\\') ++xc;
2919  if(!*xc) ;
2920  else ++xc;
2921  if(!*xc)
2922  {
2923  sprintf(Aerror,"Label :%s not found",cmd+iex);
2924  yex=IDNO;
2925  break; // label not found
2926  }
2927  }
2928  }
2929  break;
2930 
2931  case '!': // internal counter, only + or -
2932  { int j=iex+1; while(cmd[j]==' ') ++j;
2933  switch(cmd[iex])
2934  {
2935  case '=':
2936  iN=(cmd[j])?(long)comma(cmd+j):(long)comma(inpu);
2937  break;
2938  case '+':
2939  iN+=(cmd[j])?(long)comma(cmd+j):(long)comma(inpu);
2940  break;
2941  case '-':
2942  iN-=(cmd[j])?(long)comma(cmd+j):(long)comma(inpu);
2943  break;
2944  case 'X':
2945  case '*':
2946  iN=iN*((cmd[j])?(long)comma(cmd+j):(long)comma(inpu));
2947  break;
2948  case '/':
2949  {
2950  long divi=(cmd[j])?(long)comma(cmd+j):(long)comma(inpu);
2951  if(!divi) divi=1E-22;
2952  iN=iN/divi;
2953  }
2954  break;
2955  case '%':
2956  iN=iN%((cmd[j])?(long)comma(cmd+j):(long)comma(inpu));
2957  break;
2958  }
2959  }
2960  break;
2961  case '=': // iV -> iZ
2962  case '+': // iZ + iV
2963  case '-': // iZ - iV
2964  case 'X': // iZ * iV
2965  case '/': // iZ / iV
2966  {
2967  xiN=iN; xiZ=iZ; // fuer eval() wichtig!
2968  while(cmd[iex]==' ') ++iex;
2969  switch(*cmd)
2970  {
2971  case '=':
2972  iZ=((cmd[iex])?eval(cmd+iex):eval(inpu));
2973  break;
2974  case '+':
2975  iZ+=((cmd[iex])?eval(cmd+iex):eval(inpu));
2976  break;
2977  case '-':
2978  iZ-=((cmd[iex])?eval(cmd+iex):eval(inpu));
2979  break;
2980  case 'X':
2981  iZ=iZ*((cmd[iex])?eval(cmd+iex):eval(inpu));
2982  break;
2983  case '/':
2984  {
2985  double divi=(cmd[iex])?eval(cmd+iex):eval(inpu);
2986  if(!divi) divi=1E-22;
2987  iZ=iZ/divi;
2988  }
2989  break;
2990  }
2991  break;
2992  }
2993 
2994  case 'û': // evaluate expression
2995  {
2996  xiN=iN; xiZ=iZ;
2997  char *b; b=(cmd[iex])?cmd+iex:inpu;
2998  sprintf(getzeil,"%f",eval(b));
2999  int j=strlen(getzeil)-1; // 0 und . hinten wegnehmen
3000  while(j && getzeil[j]=='0') getzeil[j--]=0;
3001  if(getzeil[j]=='.') getzeil[j]=0;
3002  strcpy(inpu,getzeil);
3003  break;
3004  }
3005 
3006  case '4': // flip ixyz=x abc : set function and label of flip button i
3007  {
3008  char cmi=cmd[iex]; // das i von flip i...
3009  char *cm=cmd+iex+1, *cmf;
3010  if(!cmi) { cmi=*inpu; cm=inpu+1; } // flip ohne Arg.
3011  else if(!*cm) cm=inpu; // flip i und nichts dahinter
3012  char *tt=strchr(cm,'|'); // tooltip f. button
3013  if(tt) *tt++=0;
3014  if((cmf=strchr(cm,'='))!=0) *cmf++=0;
3015 // #ifdef A99 // Flip-Buttons hat nur a99
3016  switch(cmi)
3017  {
3018  case '1':
3019  if(*cm)
3020  {
3021  m_flip1.SetWindowText(cm);
3022  }
3023  break;
3024  case '2':
3025  if(*cm)
3026  {
3027  m_flip2.SetWindowText(cm);
3028  }
3029  break;
3030  case '3':
3031  if(*cm)
3032  {
3033  m_flip3.SetWindowText(cm);
3034  }
3035  break;
3036  case '4':
3037  if(*cm)
3038  {
3039  m_flip4.SetWindowText(cm);
3040  }
3041  break;
3042  case '5':
3043  if(*cm)
3044  {
3045  m_flip5.SetWindowText(cm);
3046  }
3047  break;
3048  case '6':
3049  if(*cm)
3050  {
3051  m_flip6.SetWindowText(cm);
3052  }
3053  break;
3054  case '7':
3055  if(*cm)
3056  {
3057  m_flip7.SetWindowText(cm);
3058  }
3059  break;
3060  case '8':
3061  if(*cm)
3062  {
3063  m_flip8.SetWindowText(cm);
3064  }
3065  break;
3066  default: break;
3067  }
3068  if(!tt) { tt=cm; while(strchr(" 0123456789:&",tt[0])) ++tt; }
3069  Bank->E3Coding((CHAR *)tt,0,0);
3070  UtPinst((CHAR *)tt,900+cmi-48); // tooltip button 1 = phrase 901
3071  if(!*cm) m_rdisp.RedrawWindow();
3072 // #endif
3073  if(cmf)
3074  {
3075  strcpy(zeile,"#uXz "); // Befehl -> #uXi
3076  zeile[3]=cmi;
3077  strcpy(zeile+Cfg->skt,cmf);
3078  UtFinst((CHAR *)zeile,'X'-'a'+2049,Cfg->tgl);
3079  }
3080 
3081  break;
3082  }
3083 
3084  case '³': // flow : visualiere den Ablauf
3085  {
3086  Vmod=cmd[iex]-'0';
3087  break;
3088  }
3089 
3090  case 'K': // copy a file
3091  {
3092  char *to;
3093  answ=IDYES;
3094  if(cmd[iex]) strcpy((char *)wr,cmd+iex);
3095  else strcpy((char *)wr,inpu);
3096  to=(char *)wr; while(*to && *to!=' ') ++to;
3097  if(!*to) { answ=IDNO; break; }
3098  *to++=0;
3099  if(!CopyFile((char *)wr,to,FALSE)) answ=IDNO;
3100  break;
3101  }
3102  case '%': // size of file
3103  {
3104  FILE *fz;
3105  answ=IDYES;
3106  if(cmd[iex]) fz=fopen(cmd+iex,"rb");
3107  else fz=fopen(inpu,"rb");
3108  if(!fz) answ=IDNO;
3109  else {
3110  long sz;
3111  fseek(fz,0L,2);
3112  sz=ftell(fz);
3113  fclose(fz);
3114  sprintf(inpu,"%ld",sz);
3115  answ=IDYES;
3116  }
3117  break;
3118  }
3119  case 30: // mkdir
3120  answ=IDYES;
3121  if(cmd[iex]) strcpy(inpu,cmd+iex);
3122  if(_mkdir(inpu)==-1) answ=IDNO;
3123  break;
3124  case '5': // rename a file
3125  {
3126  char *on, *nn;
3127  answ=IDYES;
3128  if(cmd[iex]) strcpy(inpu,cmd+iex);
3129  nn=on=inpu; while(*nn!=' ') ++nn; *nn++=0;
3130  if(rename(on,nn)) answ=IDNO;
3131  break;
3132  }
3133  case '6': // delete file
3134  {
3135  answ=IDYES;
3136  if(cmd[iex]) strcpy(inpu,cmd+iex);
3137  if(unlink(inpu)) answ=IDNO;
3138  break;
3139  }
3140 
3141 // GetLongPathName is in XP only!
3142 int GetLongPName(CString strShortPath,CString& strLongPath);
3143 
3144  case '1': // fnam : Dateinamen in die iV holen
3145  {
3146  answ=IDYES;
3147  if(!cmd[iex]) strcpy(cmd+iex,inpu);
3148  Repla((CHAR *)"_/_\\_",(CHAR *)cmd+iex); // ersetze / durch \ (sonst geht's nicht immer)
3149  if(cmd[iex]=='S' && cmd[iex+1]==' ') // fname S longname -> shortname
3150  {
3151  strcpy(wr,cmd+iex+2);
3152  if(!GetShortPathName((char *)wr,getzeil,256)) { answ=IDNO; break; }
3153  strcpy(inpu,getzeil);
3154  break;
3155  }
3156 
3157  if(cmd[iex]=='L' && cmd[iex+1]==' ') // fname L shortname -> longname
3158  {
3159  CString shrt;
3160  CString lng;
3161 /*
3162  WIN32_FIND_DATA fln;
3163  strcpy(getzeil,cmd+i+2);
3164  if(FindFirstFile(getzeil,&fln)==INVALID_HANDLE_VALUE) { *inpu=0; answ=IDNO; break; }
3165  strcpy(inpu,fln.cFileName);
3166 */
3167 // strcpy(wr,cmd+i+2);
3168  shrt=cmd+iex+2;
3169 // if(!GetLongPName((char *)wr,getzeil,256)) { answ=IDNO; break; }
3170  GetLongPName(shrt,lng);
3171  sprintf(getzeil,"%s",lng);
3172  strcpy(inpu,getzeil);
3173  break;
3174  }
3175 
3176  char o=cmd[iex];
3177  if(o=='|' || o=='>') // fnam |type or fnam >type
3178  {
3179  BOOL dm=0; CTime ctm; CString cts;
3180  if(cmd[iex+1]=='.') { dm=1; ++iex; } // directory mode: fnam >.type
3181  while (isspace(cmd[++iex]));
3182  if(o=='>') outOpen(); // open output file
3183  *inpu=0;
3184  CFileFind finder;
3185  sprintf(getzeil,"%s",cmd+iex);
3186  BOOL bW=finder.FindFile(getzeil); // 0 if no .ALD
3187  if(!bW) { answ=IDNO; break; }
3188  while (1)
3189  {
3190  if(!bW) { break; }
3191  bW = finder.FindNextFile();
3192  if(finder.IsDots()) continue;
3193  if(finder.IsDirectory()) { if(!dm) continue; } else if(dm) continue;
3194  if(o=='|')
3195  {
3196  if(*inpu) strcat(inpu,"|");
3197  sprintf(inpu+strlen(inpu),"%s",(LPCTSTR)finder.GetFileName());
3198  if(strlen(inpu)>120000) { answ=IDCANCEL; break; }
3199  }
3200  else if(dm)
3201  {
3202  fprintf(ouF,"%-16s\r\n",(LPCTSTR)finder.GetFileName());
3203  }
3204  else
3205  { finder.GetLastWriteTime(ctm); cts=ctm.Format("%Y%m%d/%H:%M:%S");
3206  fprintf(ouF,"%s -- %-16s -- %12ld\r\n",cts,(LPCTSTR)finder.GetFileName(),finder.GetLength());
3207  }
3208  }
3209  }
3210  else { // fname bez|type
3211  *inpu=0;
3212  expDef(cmd+iex,1);
3213  if(!*inpu) answ=IDNO;
3214  }
3215  }
3216  break;
3217 
3218  case '7': // flex : send exflex; message for another a99 to execute it
3219  {
3220  int nRetCode = 0;
3221  {
3222  long a=0L,b=0L; // code the name into 2 32bit numbers
3223  if(cmd[iex]) strcpy(inpu,cmd+iex);
3224  char *p=strchr(inpu,'.'); if(p) *p=0;
3225  if(ouF) fclose(ouF); ouF=0;
3226  while(1)
3227  {
3228  p=inpu;
3229  a=p[0]*16777216L;
3230  if(p[1]) a+=p[1]*65536L; else break;
3231  if(p[2]) a+=p[2]*256L; else break;
3232  if(p[3]) a+=p[3]; else break;
3233  if(p[4]) b=p[4]*16777216L; else break;
3234  if(p[5]) b+=p[5]*65536L; else break;
3235  if(p[6]) b+=p[6]*256L; else break;
3236  if(p[7]) b+=p[7];
3237  break;
3238  }
3239  xecflg=0;
3240  nRetCode=::SendMessage(HWND_BROADCAST,WM_USERCHANGED,a,b);
3241  xecflg=1;
3242  }
3243  break;
3244  }
3245 
3246  case '8': // show
3247  {
3248  int ff=flxflg; flxflg=2;
3249  if(cmd[iex]=='<') OnBack();
3250  else if(cmd[iex]=='>') OnForw();
3251  else if(cmd[iex]=='S') m_recn.SetWindowText(inpu); // show Stat : copy iV to status field
3252  else if(cmd[iex]=='b') OnShowBm(); // show bookm
3253  else if(cmd[iex]=='h') { flxflg=0; ActRset(2); } // show hist
3254  else if(cmd[iex+2]=='c') // show record
3255  OnRecDisp();
3256  else if(strchr("I+B",cmd[iex])) // show IV : iV to display
3257  {
3258  showIV(cmd+iex,inpu);
3259  }
3260  else if(cmd[iex]=='l') // show list
3261  { answ=IDYES;
3262  if(rsize==0) { answ=IDNO; break; }
3263  flxflg=fF=0; OnRset(); return 0;
3264  }
3265  else if(cmd[iex]=='L') // show Erg
3266  { ResList(0,0,rsize); m_rdisp.SetSel(1,1); m_list.SetFocus(); }
3267  else if(cmd[iex+2]=='s') // show reserve
3268  OnBackGDsp();
3269  else if(cmd[iex]=='p')
3270  if(cmd[iex+2]=='o') setAbfList(Cfg); // show prompt
3271  else if(cmd[iex+1]=='h') { m_start.SetWindowText("p"); fowi=3; OnDefault(); } // show phras
3272  else ResList(3); // show print
3273  else if(cmd[iex]=='P') // show Print
3274  ResList(2);
3275  else if(cmd[iex]=='s' || cmd[iex+1]=='r') // show sets, show erg
3276  OnButton4();
3277  else if(cmd[iex]=='c') // show cfg
3278  setCFGList(Cfg);
3279  else if(cmd[iex]=='k') // show keys
3280  ShowKeys(1);
3281  else if(cmd[iex]=='i') // show iv
3282  { m_enter.SetWindowText(inpu); m_enter.SetFocus();
3283  m_enter.RedrawWindow(); m_enter.SetSel(1000,1000);
3284  }
3285  else if(cmd[iex]=='o' || cmd[iex]=='Q') // show offline
3286  { if(!fsi) { answ=IDNO; break; } flxflg=fF=0; OnButtonB(); return 0; }
3287  else if(cmd[iex]=='a') // show about
3288  OnAbout();
3289  flxflg=ff;
3290  break;
3291  }
3292  case 23:
3293  if(cmd[iex]=='p') // print p name: change print param
3294  {
3295  if(cmd[iex+1]==' ' && cmd[iex+2]) strcpy(prnN,cmd+iex+2);
3296  else strcpy(prnN,inpu);
3297  if(Lox) delete Lox;
3298  Lox=new EXET(prnN,Cfg,0, dbDir);
3299  if(!*Aerror) Lox->ExOutf(putBuff);
3300  else { if(Lox) Lox; Lox=0; }
3301  }
3302  else OnPrintDisp(); // print = printer button
3303  break;
3304  case 21: // first
3305  case 20: // last
3306  if(*cmd==21)
3307  {
3308  if(cmd[iex]=='o') { nrec=nrec1=0; irn=0; } // first offline
3309  else if(cmd[iex]=='$') // first $0 / $1 : set varlist a/A pointer
3310  {if(cmd[iex+1]=='0') va=uva.GetStartPosition(); else vA=uvA.GetStartPosition(); }
3311  else if(cmd[iex]=='#') // first of database
3312  {
3313  irn=1L;
3314  int r=dbFetch(1L,0);
3315  if(r<0) { while(dbFetch(++irn,0)<0L) ; answ=IDNO; }
3316  break;
3317  }
3318  else if(cmd[iex]=='s') // first subrec
3319  {
3320  m_list.SetCurSel(0); // wg. Formular
3321  Rec->cri=0; break;
3322  }
3323  else if(cmd[iex]=='v') // first vi
3324  {
3325  if(!vwF) { answ=IDCANCEL; *inpu=0; break; }
3326  vwn=0;
3327  fseek(vwF,(long)vwn*vwl,0);
3328  fgets(inpu,vwl,vwF);
3329  inpu[vwl-2]=0; // help or flx ?
3330  break;
3331  }
3332  else // first of res set
3333  {
3334 // sprintf(Aerror,"rsize=%d, resT=%d",rsize,resT); MessageBox(Aerror); *Aerror=0;
3335  if(rsize<1 || !rsF) { answ=IDNO; break; }
3336  if(!resT) fseek(rsF,0L,0); else fseek(rsF,4L,0);
3337  if(rsize==1) { int f=flxflg; flxflg=1; OnBup(); irn=Rec->rNr; counter(rsn,rsize); flxflg=f; answ=IDYES; break; }
3338  }
3339  }
3340  else // last
3341  {
3342  if(cmd[iex]=='o') nrec1=nrec=fsi-1; // last offline
3343  else if(cmd[iex]=='#') // last #: last rec in db
3344  {
3345  irn=Bank->InMaxRecNr();
3346  if(dbFetch(0L,0)<0) { while(dbFetch(--irn,0)<0) ; answ=IDNO; }
3347  break;
3348  }
3349  else if(cmd[iex]=='s') // last Subrec
3350  { int p;
3351  Rec->cri=Rec->gri-2;
3352  if((p=Rec->SubPre(0))==-1) { answ=IDNO; Rec->cri=0; }
3353  else Rec->cri=p;
3354  break;
3355  }
3356  else // last : in result set
3357  {
3358  if(!rsize) { answ=IDNO; break; }
3359  if(!resT) fseek(rsF,-2L,2); else fseek(rsF,-4L,2);
3360  if(rsize==1) { int f=flxflg; flxflg=1; OnBup(); irn=Rec->rNr; counter(rsn,rsize); flxflg=f; answ=IDYES; break; }
3361  }
3362  } // fallthru
3363 
3364  if(cmd[iex]=='o')
3365  { if(fsi==0) { nrec=nrec1=-1; irn=0; answ=IDNO; } // last off
3366  else { flxflg=1; answ=IDYES; Fetch(nrec); irn=Rec->rNr; flxflg=0; }
3367  break;
3368  }
3369  case 5: // next
3370  {
3371  answ=IDYES;
3372  int f=flxflg; flxflg=1;
3373  if(cmd[iex]=='$') // next $0 / $1 : next var in uva / uvA
3374  {
3375  *inpu=0;
3376  if(cmd[iex+1]=='0')
3377  {
3378  if(va){ uva.GetNextAssoc(va,uvn,uvc);
3379  sprintf(inpu,"$%s %s",LPCTSTR(uvn),LPCTSTR(uvc));
3380  }
3381  else answ=IDNO;
3382  }
3383  else
3384  {
3385  if(vA) { uvA.GetNextAssoc(vA,uvn,uvc);
3386  sprintf(inpu,"$%s %s",LPCTSTR(uvn),LPCTSTR(uvc));
3387  }
3388  else answ=IDNO;
3389  }
3390  }
3391  else if(cmd[iex]=='#') // next #
3392  {
3393  irn=Rec->rNr; int r;
3394  if(!mrn) mrn=Bank->InMaxRecNr();
3395  r=-2;
3396  while(r<-1) { ++irn; if(irn>mrn) { r=-1; break; } r=dbFetch(irn,0); }
3397  if(r<-1) { answ=IDNO; *Aerror=0; } // no rec under this #
3398  else if(r<0) answ=IDCANCEL; // beyond the end
3399  else counter(irn,mrn);
3400  flxflg=f;
3401  break;
3402  }
3403  else if(cmd[iex]=='r')
3404  {
3405  *Aerror=1;
3406  if(iOnBup()==0) answ=IDNO;
3407  else
3408  {
3409  irn=atol(Aerror);
3410  Bank->InSTL(irn,(CHAR *)inpu,0);
3411  }
3412  *Aerror=0;
3413  flxflg=f;
3414  break;
3415  }
3416  else if(cmd[iex]=='o') { if(iOnButtonN()==-1) answ=IDNO; flxflg=f; }
3417  else if(cmd[iex]=='s') { int p=Rec->SubNxt(Rec->cri);
3418  if(p==-1) answ=IDNO;
3419  else Rec->cri=p;
3420  if(limo!=1) OnRecDisp();
3421  m_list.SetCurSel(p);
3422  flxflg=f;
3423  }
3424  else if(cmd[iex]=='v') // next vi
3425  {
3426  if(!vwF) { answ=IDCANCEL; *inpu=0; break; }
3427  ++vwn;
3428  if(vwn>=vwz) { answ=IDNO; *inpu=0; break; }
3429  fseek(vwF,(long)vwn*vwl,0);
3430  fgets(inpu,vwl,vwF);
3431  inpu[vwl-2]=0; // help or flx ?
3432  flxflg=f;
3433  break;
3434  }
3435  else if(rsize<1 || iOnBup()==0) { answ=IDNO; counter(1,1); flxflg=f; }
3436  else { irn=Rec->rNr; counter(rsn,rsize); flxflg=f; }
3437  if(answ!=IDNO) irn=Rec->rNr;
3438  }
3439  break;
3440  case 6: // prev
3441  {
3442  answ=IDYES;
3443  int f=flxflg; flxflg=1;
3444  if(cmd[iex]=='#') // prev #
3445  {
3446  irn=Rec->rNr-1L;
3447  if(irn<1L) { answ=IDCANCEL; break; }
3448  if(!mrn) mrn=Bank->InMaxRecNr();
3449  while(dbFetch(irn,0)<0) { if(irn<1L) { answ=IDCANCEL; break; } --irn; }
3450  if(answ!=IDCANCEL) counter(irn,mrn);
3451  flxflg=f;
3452  break;
3453  }
3454  else if(cmd[iex]=='o') { if(iOnButtonP()==-1) answ=IDNO; else irn=0; flxflg=f; }
3455  else if(cmd[iex]=='s') {
3456  int p;
3457  if(!Rec->cri) p=-1; else p=Rec->SubPre(Rec->cri);
3458  if(p==-1) answ=IDNO;
3459  else Rec->cri=p;
3460  if(limo!=1) OnRecDisp();
3461  m_list.SetCurSel(p);
3462  flxflg=f;
3463  }
3464  else { if(iOnBdn()==0) { answ=IDNO; counter(1,1); }
3465  else irn=Rec->rNr;
3466  flxflg=f;
3467  }
3468  if(answ!=IDNO) irn=Rec->rNr;
3469  }
3470  break;
3471  case 11: // repeat (obsolete)
3472  case 'k':
3473  if(cmd[1]!='a') // keycheck : wurde eine Taste gedrueckt?
3474  {
3475  int j=IDNO; int k=0; int q=cmd[iex];
3476  MSG message;
3477  if(flxflg==3) j=MessageBox(uif[23],"BREAK",MB_YESNO | MB_ICONQUESTION);
3478  else
3479  while(::PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
3480  {
3481  ::TranslateMessage(&message);
3482  k=message.wParam;
3483  if(message.message==WM_CHAR)
3484  if(k == 27)
3485  {
3486  j=MessageBox(uif[23],"BREAK",MB_YESNO | MB_ICONQUESTION);
3487  break;
3488  }
3489  else if(q!=0) { *inpu=k; inpu[1]=0; j=IDYES; break; }
3490  ::DispatchMessage(&message);
3491  }
3492  if(*cmd==9)
3493  { fF=0;
3494  if(j==IDYES) return 0;
3495  return 1;
3496  }
3497  answ=j;
3498  }
3499  else // kalend : Kalendersatz verarb
3500  if(cmd[2]=='l') // inpu -> kal[]
3501  {
3502  kalend(inpu);
3503  }
3504  else // katlist : write list of fields into katlist.txt
3505  {
3506  int n=0, N; N=Cfg->numk;
3507  FILE *katlist=fopen("katlist.asy","w+t");
3508  if(!katlist) { answ=IDNO; break; }
3509  answ=IDYES;
3510  while(n<N-1)
3511  { strcpy(zeile,LPCTSTR(Kat[n++])); // ist ANSI!
3512  if(cmod=='0') Bank->E3Coding((CHAR *)zeile,0,1); // ANSI -> ASCII
3513  fprintf(katlist,"#%s\n",zeile);
3514  }
3515  fclose(katlist);
3516  }
3517  break;
3518 
3519  case 10: // save
3520  flxflg=1;
3521  if(cmd[iex]=='e') OnMSave(); // save edit
3522  else if(cmd[iex]=='o') OnM291(); // save off
3523  else if(cmd[iex]=='r') OnM266(); // save result
3524  else if(cmd[iex]=='p') // save phrases
3525  {
3526  while(cmd[iex] && cmd[iex++]!=' ') ;
3527  strcpy(zeile,phrN);
3528  if(cmd[iex]) strcpy(phrN,cmd+iex); else strcpy(phrN,inpu);
3529  aph_save();
3530  strcpy(phrN,zeile);
3531  break;
3532  }
3533  else if(cmd[iex]=='v') // save view
3534  {
3535  int j;
3536  if(!vwF) break;
3537  while(cmd[iex] && cmd[iex++]!=' ') ;
3538  if(cmd[iex]) j=atoi(cmd+iex); else j=vwn;
3539  if(j>vwz && j<0) { answ=IDNO; break; }
3540  vwn=j;
3541  fseek(vwF,(long)vwn*vwl,0);
3542  j=strlen(inpu);
3543  if(j<vwl) { while(j<vwl) inpu[j++]=' '; }
3544  inpu[vwl-2]=0;
3545  fputs(inpu,vwF);
3546  break;
3547  }
3548  flxflg=0;
3549 
3550  break;
3551 
3552  case 16: // spaces: remove mult spaces from iV
3553  {
3554  char *a,*b; a=b=inpu;
3555  while(*a)
3556  { if(!isspace(*a)) // normalzeichen
3557  { *b++=*a;
3558  if(*a==34 || *a==39) // zw. quotes: nichts aendern
3559  {
3560  char c=*a++;
3561  while(*a && *a!=c && *a!='>') *b++=*a++;
3562  if(*a) *b++=*a++;
3563  }
3564  else ++a;
3565  }
3566  else // space
3567  { *b++=' '; while(isspace(*++a)); // Aus " = " wird "="
3568  }
3569  if(*a=='=')
3570  { while(isspace(*++a));
3571  if(*a==34 || *a==39)
3572  {
3573  if(b[-1]==' ') b[-1]='='; // aus = '...' wird ="..."
3574  else *b++='=';
3575  *b++=*a;
3576  if(*a==34 || *a==39)
3577  { b[-1]=34; char c=*a++;
3578  while(*a && *a!=c && *a!='>') *b++=*a++;
3579  if(*a==c) *b++=34;
3580  }
3581  ++a;
3582  }
3583  else { *b++='='; --a; }
3584  }
3585  }
3586  *b=0;
3587  }
3588  break;
3589 
3590  case '*': // *#nnn_abc_def_ : field-specific srch+repl
3591  jex=(Rec->FSrRp((CHAR *)cmd,1))?1:0;
3592  case '_':
3593  case ',': // _abc_xyz or ,abc,xyz, : general srch+repl
3594  if(*cmd!='*')
3595  jex=(Rec->SrRp((CHAR *)cmd,Rec->ga[0],1,0,1))?1:0 ;
3596  if(jex)
3597  {
3598  ++chf; // to signal a change
3599  setFldList(Rec);
3600  rst=rst|CHG;
3601  OnDBP(); // refresh display
3602  }
3603  break;
3604  case 'ä': // call / cAll external prog (A for minimized)
3605  case 'C': // Call / CAll external prog, no wait
3606  { char *a; int j=0;
3607  if(ouF) fclose(ouF); ouF=0;
3608  if(cmd[iex]) a=cmd+iex;
3609  else a=inpu;
3610 // while(*a) { wr[j++]=*a; if(a[-1]!=' ' && *a=='\\' && a[1]=='\\') ++a; ++a; }
3611 // wr[j]=0;
3612  strcpy(wr,a);
3613  callProg((char *)wr, cmd);
3614  }
3615  break;
3616  case 28: // dos
3617  case 29: // Dos
3618  {
3619 extern int expipe(char *);
3620  char *e; char *a; if(cmd[iex]) a=cmd+iex; else a=inpu;
3621  e=getenv("COMSPEC");
3622 // sprintf((char *)wr,"%s /c %s >dostxt.txt",e,a);
3623 // if(*cmd==28) { unlink("dostxt.txt"); callProg((char *)wr,"cA"); } // helpinfo("dostxt.txt","?");
3624  sprintf((char *)wr,"%s /c %s",e,a);
3625  if(*cmd==28) callProg((char *)wr,"cA");
3626  else callProg((char *)wr,"Ca");
3627 // Versuch:
3628 // else { int ec=expipe((char *)wr); sprintf(inpu,"ec=%d",ec); MessageBox(Aerror,inpu); }
3629  }
3630  break;
3631  case 96: // activate
3632  {
3633  if(cmd[iex]=='4')
3634  {
3635  int f=m_rdisp.GetFirstVisibleLine();
3636  f=m_rdisp.LineIndex(f); m_rdisp.SetSel(f,f);
3637  m_rdisp.SetFocus(); scA=0;
3638  }
3639  if(cmd[iex]=='2') m_enter.SetFocus();
3640  if(cmd[iex]=='3') m_start.SetFocus();
3641  if(cmd[iex]=='1') m_list.SetFocus();
3642  if(!cmd[iex]) // activate : bring a99 to foregnd and activate
3643  { // not really easy ...
3644 // CWnd* Fw; Fw=GetForegroundWindow();
3645 // if(Fw!=this) Fw->ShowWindow(SW_MINIMIZE);
3646  if(!winxi->IsIconic()) iMinim();
3647 // UpdateWindow();
3648 
3649  SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
3650  SetWindowPos(&wndNoTopMost,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
3651  ShowWindow(SW_HIDE);
3652  ShowWindow(SW_MINIMIZE); // ohne dieses geht's einfach nicht, zum Kuckuck!
3653  ShowWindow(SW_RESTORE);
3654 
3655 // diverse Tests
3656 // Fenster muss aktiviert werden, d.h. Tastatureingabe zugeordnet kriegen (Focus)
3657 // das Folgende klappt aber alles nicht:
3658 // ::DefWindowProc(this->m_hWnd,WM_ACTIVATE,0,0);
3659 // CDialog::OnInitDialog();
3660 // SendMessage(WM_INITDIALOG,(HWND)m_list.m_hWnd,0);
3661 // SetForegroundWindow();
3662 // SetFocus(); m_list.SetFocus();
3663 // mwplace.showCmd=SW_SHOWNORMAL;
3664 // SetWindowPlacement(&mwplace);
3665 // _sleep(100); // bringt nichts
3666 // SetActiveWindow(); // nicht noetig !?
3667 // SetFocus(); // wohl auch nicht noetig
3668 // m_list.SetFocus();
3669 // ::SetFocus(this->m_hWnd);
3670 // SetFocus();
3671 // ::SetFocus(this->m_hWnd);
3672 // EnableWindow();
3673 // SetActiveWindow();
3674 // SetForegroundWindow();
3675 // m_list.EnableWindow();
3676 // m_list.SetFocus();
3677  // this->SetFocus(); m_list.SetFocus();
3678  // OnLButtonDown(MK_LBUTTON,(1,1));
3679 // ShowWindow(SW_SHOW);
3680 // OnMouseActivate( this, HTNOWHERE, MA_ACTIVATEANDEAT );
3681 // if(Fw!=this) { Fw->ShowWindow(SW_HIDE); Fw->ShowWindow(SW_SHOWNA); }
3682 // m_list.SendMessage(WM_KEYDOWN,VK_DOWN);
3683 // SendInput(1,INPUT_MOUSE,10,10,0,MOUSEEVENTF_LEFTDOWN,0,0,20);
3684 // SendMessage(WM_LBUTTONDOWN,MK_LBUTTON,65537);
3685 
3686 // ShowWindow(SW_HIDE);
3687  // Einzige bekannte Alternative: (aber langsamer und irritierend wg. "Animation")
3688 // ShowWindow(SW_MINIMIZE);
3689 // ShowWindow(SW_RESTORE);
3690 // m_list.SetCapture();
3691 // m_list.SendMessage(WM_LBUTTONDOWN,MK_LBUTTON,0);
3692 // ::ReleaseCapture();
3693  }
3694  }
3695  break;
3696 
3697  case '@': // ask question
3698  {
3699  flxflg=2; // FLEX running
3700  answ=IDYES;
3701  if(cmd[iex]) strcpy(wr,cmd+iex); else strcpy(wr,inpu);
3702  if(*wr=='@') // ask name=pswd
3703  {
3704  GetP *m_getp;
3705  m_getp = new GetP(this);
3706  m_getp->Ask((char *)wr+1);
3707  delete m_getp;
3708  m_getp=0;
3709  }
3710  else
3711  {
3712  m_getl = new GetL(this);
3713  m_getl->Ask((char *)wr);
3714  delete m_getl;
3715  m_getl=0;
3716  }
3717 
3718  flxflg=0; // FLEX running
3719  }
3720  break;
3721 
3722  case 'M': // Message
3723  {
3724  int sek; char *r;
3725  flxflg=2; // FLEX running
3726  if(cmd[iex]) strcpy(wr,cmd+iex); else strcpy(wr,inpu);
3727  Msg *m_msg;
3728  m_msg = new Msg();
3729  r=strchr((char *)wr,','); if(r) { sek=atoi((char *)wr), strcpy(wr,r+1); } else sek=10;
3730  m_msg->msg((char *)wr,sek);
3731  delete m_msg;
3732  flxflg=0; // FLEX running
3733  }
3734  break;
3735 
3736  case 'a': // ansi / ascii : switch coding if iV
3737  {
3738 // if(cmd[1]=='s') Bank->E3Coding((CHAR *)inpu,0,1); // ANSI -> ASCII
3739 // else Bank->E3Coding((CHAR *)inpu,0,0); // ASCII -> ANSI
3740  if(cmd[1]=='s') Dsp->E3Coding((CHAR *)inpu,0,1); // asci ANSI -> ASCII //V26
3741  else if(cmd[1]=='n') Dsp->E3Coding((CHAR *)inpu,0,0); // ansi ASCII -> ANSI
3742  else if(cmd[1]=='S') Bank->E3Coding((CHAR *)inpu,0,1); // aSci
3743  else if(cmd[1]=='N') Bank->E3Coding((CHAR *)inpu,0,0); // aNsi ASCII -> ANSI
3744  break;
3745  }
3746  case 2: // select
3747  {
3748  char *s;
3749  s=cmd+iex;
3750  m_selb = new selbox(this);
3751  answ=IDYES;
3752  if(*s=='?') { sprintf(zeile,"Help=%s",hlist+1); s=zeile; }
3753  if(!*s) s=inpu;
3754  m_selb->Sel(s);
3755 // if(!*inpu) yex=IDNO;
3756  delete m_selb;
3757  }
3758  break;
3759  case 'T': // date (Timestamp->inpu)
3760  {
3761  int lg=0;
3762  SyTime((CHAR *)inpu);
3763  if(cmd[iex]) lg=atoi(cmd+iex);
3764  if(lg) inpu[lg]=0;
3765  }
3766  break;
3767 
3768  case 'ì': // pipe : start a program, then read its stdout
3769  case 'O': // open file oder open x oder open x file
3770  if(cmd[iex]=='d' && (!cmd[iex+1] || cmd[iex+1]==' ')) { TempOpen(); break; }
3771  if(cmd[iex]=='x' && !cmd[iex+1]) sprintf(cmd+iex,"x %s",inpu);
3772 // kein x vor dem Namen? Dann zum Lesen oeffnen
3773  if((!cmd[iex] && (*inpu!='x' || inpu[1]!=' ')) || (cmd[iex]!='x' || cmd[iex+1]!=' '))
3774  {
3775  if(cmd[iex]) strcpy(zeile,cmd+iex);
3776  else strcpy(zeile,inpu);
3777  if(xF) fclose(xF);
3778  if(Fty==2) InterClose();
3779  Fty=0;
3780  if(*cmd=='O')
3781  {
3782  if(strstr(zeile,"://")) // http:// or file:///
3783  {
3784  if(InterOpen(zeile)==-1) answ=IDCANCEL;
3785  else { Fty=2; answ=IDYES; }
3786  break;
3787  }
3788  else xF=fopen(zeile,"rb");
3789  }
3790  else { Fty=1; xF=_popen(zeile,"rt"); }
3791  if(!xF) { answ=IDNO; break; }
3792  else
3793  {
3794 // setvbuf( xF, NULL, _IOFBF, 256000 ); // buffering for speed - bringt nix
3795  answ=IDYES;
3796  fseek(xF,0L,2);
3797  fsz=ftell(xF);
3798  fseek(xF,0L,0);
3799  break;
3800  }
3801  }
3802  if(cmd[iex]=='x') ; // fallthru open x == dow f
3803  else strcpy(cmd+iex,inpu);
3804  cmd[iex]='f';
3805 
3806  case 'D': // Download via PrintParam
3807  if(cmd[iex]!='f')
3808  {
3809  if(!Lox) { Lox=new EXET(prnN,Cfg,0, dbDir);
3810  if(*Aerror) Lox=new EXET("p-w0",Cfg,0, dbDir);
3811  if(*Aerror) break;
3812  }
3813  Lox->ExOutf(putout);
3814  }
3815  // fallthru
3816 
3817  case 'd': // export (=download) via ExportParam
3818  answ=IDYES;
3819  OUt=Out;
3820  if(*cmd=='D') Out=Lox;
3821 //if(!Out) MessageBox("No Output defined");
3822 // if(!Out) break; // no export object
3823  if(cmd[iex]=='s' && rsize>0) OnButtonPrint(2); // exp set
3824  else if(cmd[iex]=='d') OnButtonPrint(11); // exp database
3825  else if(cmd[iex]=='v' && vwF)
3826  { int i=rsize; rsize=0; OnButtonPrint(2); rsize=i; break; } // exp view
3827  else if(cmd[iex]=='b') { if(rsize>0 || vwF) ResList(5); break; } // exp brief
3828  else if(cmd[iex]=='f' && cmd[iex+1]=='a') // exp fam
3829  {
3830  answ=Family(Rec); // is there a family?
3831  if(answ==IDNO) OnButtonPrint(0); // no
3832  else // yes
3833  {
3834  int i=0;
3835  while(i<anzFam) { dbFetch(result[i++],0); OnButtonPrint(0); }
3836  }
3837  }
3838  else if(cmd[iex]=='f') // export file ...
3839  {
3840  while(cmd[iex] && cmd[iex]!=' ') ++iex;
3841  if(!cmd[iex] || !cmd[iex+1]) strcpy(zeile,inpu);
3842  else strcpy(zeile,cmd+iex+1);
3843  if(ouF) fclose(ouF);
3844 // kann die Datei zum Schreiben geoeffnet werden?
3845  if(*zeile=='?') OnButtonPrint(6);
3846  else if (*zeile=='+') ouF=fopen(zeile+1,"a"); else ouF=fopen(zeile,"a");
3847  if(!ouF) answ=IDNO;
3848  else
3849  {
3850  fclose(ouF); ouF=0; answ=IDYES;
3851  if(!*outN0) strcpy(outN0,outN); // save the initial name
3852  strcpy(outN,zeile);
3853  if(*outN=='+') { strcpy(outN,outN+1); ++out; }
3854  else { unlink(outN); out=0; }
3855  }
3856  }
3857  else if(cmd[iex]=='p' || cmd[iex]=='t') // export param or export table
3858  {
3859  char md=cmd[iex];
3860  char *pa;
3861  while(cmd[iex] && cmd[iex]!=' ') ++iex;
3862  if(!cmd[iex]) pa=inpu; else pa=cmd+iex;
3863  while(*pa==' ') ++pa;
3864  if(!*pa) break;
3865  if(*pa=='?') OnButtonPrint(7);
3866  else
3867 // if(strcmp(expN,pa)) // same name? don't load again
3868 // {
3869  if(md=='p')
3870  {
3871  strcpy(expN,pa);
3872  *wlab=0; // exp wX ruecksetzen
3873  if(Out)
3874  if(Out==Out1)
3875  { delete Out1; expN=expN1;
3876  Out=Out1=new EXET(expN,Cfg,0, dbDir); // export p
3877  }
3878  else
3879  { delete Out2; expN=expN2;
3880  Out=Out2=new EXET(expN,Cfg,0, dbDir); // export p for Out2
3881  }
3882  else Out=Out1=new EXET(expN,Cfg,0, dbDir); // export p
3883 
3884  if(!*Aerror)
3885  { if(Out)
3886  if(cmod=='1') Out->ExOutf(putoutA); else Out->ExOutf(putout);
3887  }
3888  else
3889  {
3890  answ=IDNO; *expN=0; strcpy(inpu,Aerror); *Aerror=0; break; }
3891  }
3892  else if(Out) Out->E2Exet(pa,Cfg,2); // export t
3893 // }
3894  }
3895  else if(cmd[iex]=='-' && Out && Rec->gri) // exp -label
3896  { // gedacht f. Manipulationen am Datensatz (GM-Parameter)
3897  Out->ExOutf(putinpu); // echten output verhindern
3898  Out->Exp(Rec,1,(CHAR *)cmd+iex+1);
3899  Out->ExOutf(putout);
3900  break;
3901  }
3902  else if(cmd[iex]=='o') // exp off
3903  { if(!fsi) answ=IDNO; else OnPr1(); }
3904  else if(cmd[iex]=='H') if(Out) OnButtonPrint(0,"\02"); else ; // Kopfabschnitt ausf.
3905  else if(cmd[iex]=='F') if(Out) OnButtonPrint(0,"\01"); else ; // Fussabschnitt ausf.
3906  else if(cmd[iex]=='R') Bank->InV14Repl(Rec,1); // V14-Ersetzungen ausfuehren
3907  else if(cmd[iex]=='V') // exp V : VS-sequenzen ersetzen
3908  {
3909  int j=0; CHAR *gr;
3910  if((fend-fr)>fspace-3000) { sprintf(Aerror,"not enough backgr. space for exp V\nincrease mB variable in CFGi /%ld)",fend-fr); MessageBox(Aerror); break; }
3911  while(j<Rec->gri)
3912  { strcpy(fend+1,Rec->ga[j]); Bank->rcd=2;
3913  gr=Bank->ExRcode(fend+1); // Umcodierung ausfuehren
3914  if(*gr==RS) gr+=2;
3915  strcpy(Awx,gr);
3916  *Aerror=8; Rec->Ins(Awx); ++j;
3917  }
3918  *Aerror=0;
3919  }
3920  else if(cmd[iex]=='w') // exp w : wri-Abschnitt in exp.param vorwaehlen
3921  {
3922  *wlab=cmd[iex+1]; if(*wlab=='0') *wlab=0;
3923  }
3924  else if(tolower(cmd[iex])=='a') // exp a/A : do diacrit exchange
3925  {
3926  if(cmd[iex+1]=='i')
3927  {
3928  UtAccent((char *)inpu,(char *)inpu+strlen(inpu),cmd[iex]-'A');
3929  }
3930  else
3931  {
3932  if(Rec->gri) UtAccent((char *)Rec->ga[0],(char *)Rec->gend,cmd[iex]-'A');
3933  if(fri) UtAccent((char *)fa[0],(char *)fend,cmd[iex]-'A');
3934  }
3935  }
3936  else OnButtonPrint(0); // exp ohne Argumennt
3937 
3938  if(Out && Out==Lox) { Lox->ExOutf(putBuff); Out=OUt; }
3939  if(*Aerror==64) answ=IDCANCEL; // bei Abbruch in OnButtonPrint()
3940  *Aerror=0;
3941  break;
3942  case 4: // form
3943  { char *fm=cmd+iex;
3944  if(!*fm) fm=inpu;
3945  int j=atoi(fm)-1;
3946  if(j<0 || j>=frmn) j=-1;
3947  if(*fm=='f' && fm[1]==' ' && fm[2]) // form f name
3948  { int f=frmn;
3949  frmn=0;
3950  if(!FormLoad(fm+2)) { answ=IDNO; frmn=f; break; }
3951  answ=IDYES;
3952  break;
3953  }
3954  if(!frmn) { answ=IDNO; break; } // there is no form!
3955  if(!isdigit(*fm)) // form name
3956  {
3957  int k=0,lg;
3958  CHAR ans[64], asc[64];
3959  strcpy(ans,fm); strcpy(asc,fm);
3960  Bank->E3Coding(ans,0,1); Bank->E3Coding(asc,0,0);
3961  lg=strlen(fm);
3962  while(k<frmn)
3963  {
3964  j=UtPfind(frm[k]);
3965  if(!strncmp(pa[j]+1,fm,lg) || !strncmp(pa[j]+1,ans,lg) || !strncmp(pa[j]+1,asc,lg)) break;
3966  ++k;
3967  }
3968  if(k<frmn) j=k; else j=-1;
3969  }
3970  if(j==-1) answ=IDNO;
3971  else
3972  {
3973  answ=IDCANCEL;
3974  flxflg=2; // FLEX running
3975  fF=0;
3976  openForm(j);
3977  if(vwF) fclose(vwF); // close view if one was opened
3978  return 0;
3979  }
3980  break;
3981  }
3982  case 22: // exec
3983 // if(subi) break; // exec auch innerhalb UP erlauben 080416
3984  if(cmd[iex]) strcpy(inpu,cmd+iex); // exec flexname -> exec X flexname
3985  if(tolower(*inpu)=='x' && inpu[1]==' ') ;
3986  else { sprintf(zeile,"X %s",inpu); strcpy(inpu,zeile); }
3987  fF=flxflg=0;
3988  if(FLEXecute(inpu)==-1) MessageBox("FLEX not found",inpu);
3989  return 0;
3990  break;
3991 
3992  case 'b': // button i / j
3993  if(subi) break;
3994  if(cmd[iex]) strcpy(inpu,cmd+iex);
3995  fF=0; flxflg=0;
3996 // if(*inpu=='f') { flxflg=0; OnButtonCmd(); return 0; } // but find abgeschafft 050520
3997  if(*inpu=='i') { OnIndex(); return 0; }
3998  if(*inpu=='j') { OnIndex2(); return 0; }
3999  return 0;
4000  break;
4001 
4002  case 1: // end
4003  yex=IDCANCEL; // damit wirklich Schluss gemacht wird
4004  // sonst Problem bei mehrfach "form" hintereinander
4005  break;
4006 
4007  case 19: // family
4008  case 'F': // find + display
4009 
4010  if(cmd[1]=='a') // Fam
4011  { answ=Family(Rec);
4012  if(answ==IDNO) break;
4013  else rsize=anzFam;
4014  if(*cmd=='F') { rwu=0; *cmd=19; }
4015  else rwu=-2;
4016 // break;
4017  }
4018  // fallthru
4019  case 'f': // find (as part of flex)
4020  if(cmd[iex]=='@') // find @ : iV is sequence of recnumbers
4021  {
4022  char *h;
4023  h=inpu;
4024  if(cmd[iex+1]!='+') rsize=0;
4025  while(*h && !isdigit(*h)) ++h;
4026  while(*h)
4027  {
4028  result[rsize++]=atol(h);
4029  while(isdigit(*h)) ++h;
4030  while(*h && !isdigit(*h)) ++h;
4031  }
4032  strcpy(zeile,"(num)"); rwu=-1; saveRset();
4033  break;
4034  }// else fall thru
4035  case 'î': // f1nd : find and load 1st rec,no res set
4036  if(cmd[iex]) strcpy(inpu,cmd+iex);
4037  if(*inpu=='$') // Sonderfall $nnn : LOG-Datei auswerten
4038  {
4039  if(OnLogPeek(atoi(inpu+1))) answ=IDYES; else answ=IDNO;
4040  break;
4041  }
4042  if(*inpu=='_' || *inpu==',') // Fulltext srch
4043  {
4044  answ=IDNO;
4045  Bac->Copy(Rec); Bac->gend[0]=EOD;
4046  xcode((char *)Bac->g,(char *)Rec->g,1); Bac->gend[0]=EOD;
4047  xcode((char *)wr,inpu,0);
4048 
4049  // Srch term is ready in wr
4050  if(inpu[1]=='*') { if(Bac->FSrRp(wr,1)!=0) answ=IDYES; } // field-specific srch
4051  else
4052  if(Bac->SrRp(wr,Bac->ga[0],1,0,0)!=0) answ=IDYES; // general srch
4053 
4054  break;
4055  }
4056 
4057  if(*inpu=='r' && isdigit(inpu[1])) // find ri : result i
4058  {
4059  answ=IDNO;
4060  int ri=atoi(inpu+1);
4061  if(ri<1 || ri>rsize) break;
4062  int ff=flxflg; flxflg=1;
4063  fseek(rsF,(long)ri*4L,0);
4064  if(iOnBup()) { irn=Rec->rNr;answ=IDYES; }
4065  flxflg=ff;
4066  break;
4067  }
4068  if(*inpu=='s')
4069  if(isdigit(inpu[1])) // find si : Set i
4070  {
4071  answ=IDNO;
4072  int si=atoi(inpu+1);
4073  if(!si) si=rss;
4074  if(si<1 || si>rss) break;
4075  int ff=flxflg; flxflg=1;
4076  if(ActRset(si)) answ=IDYES;
4077  flxflg=ff;
4078  break;
4079  }
4080  // find :name (der Erg.Menge)
4081  if(*inpu==':')
4082  { int k;
4083  answ=IDNO;
4084  k=Findrs(inpu+1); if(k==-1) break;
4085  int ff=flxflg; flxflg=1;
4086  if(ActRset(k)) answ=IDYES;
4087  flxflg=ff;
4088  break;
4089  }
4090  if(*inpu=='/' || *inpu=='-' || *inpu=='*') // add/remove curr rec from curr result set
4091  {
4092  char c=*inpu; if(c=='*') c='+';
4093  if(inpu[1]=='s') // find si : Set i
4094  {
4095  answ=IDNO;
4096  int si=atoi(inpu+2);
4097  if(!si) si=rss;
4098  if(si<1 || si>rss) break;
4099  int ff=flxflg; flxflg=1;
4100  OnButton4(); m_list.SetCurSel(si-1);
4101  if(OnFunKey(32,c)) answ=IDYES;
4102  ActRset(rss);
4103  flxflg=ff;
4104  break;
4105  }
4106  if(inpu[1]==':') // find si : Set i
4107  {
4108  answ=IDNO;
4109  int k;
4110  int ff=flxflg; flxflg=1;
4111  k=Findrs(inpu+2);
4112  if(k==-1) break;
4113  OnButton4(); m_list.SetCurSel(k-1);
4114  if(OnFunKey(32,c)) answ=IDYES;
4115  ActRset(rss);
4116  flxflg=ff;
4117  break;
4118  }
4119  if(Rec->rNr && c!='+') // aktuellen Satz rein/raus
4120  { int m=limo; limo=0;
4121  int ff=flxflg; flxflg=1;
4122  if(OnFunKey(32,c)) answ=IDYES; else answ=IDNO;
4123  ActRset(rss);
4124  limo=m; flxflg=ff;
4125  }
4126  break;
4127  }
4128  if(*inpu=='&' && !inpu[1]) // find & : SR expansion
4129  {
4130  int rs;
4131  rs=Bank->InExpand(MAXR,result,rsize);
4132  if(rs==rsize) { answ=IDNO; break; } // nichts!
4133  rsize=rs;
4134  sprintf(zeile,"%s&",srText+7);
4135  rwu=-2;
4136  saveRset();
4137  break;
4138  }
4139  // fallthru if Find/find normal command
4140 
4141  case 3: // choose: find and select a rec, then FLEX continues!
4142  {
4143  long res;
4144  Rmod=0;
4145  if(*cmd!=19) // not F
4146  {
4147  if(cmd[iex]) strcpy(zeile,cmd+iex);
4148  else { if(!*inpu) { yex=IDNO; break; } else strcpy(zeile,inpu); }
4149  flxflg=0;
4150  if(!strncmp(zeile,"offline",7)) // find offline
4151  { if(*cmd==3) { flxflg=1; rwu=0; } OnButtonB(); if(*cmd!=3) yex=IDNO; break; }
4152  if(!stricmp(zeile,"new") || !stricmp(zeile,"neu")) // New rec's
4153  { *Aerror=1; // flag
4154  flxflg=1;
4155  OnX8();
4156  *Aerror=0;
4157  if(rsize==0) answ=IDNO; else answ=IDYES;
4158  break;
4159  }
4160  if(!stricmp(zeile,"edit") || !stricmp(zeile,"edt")) // Edited rec's
4161  { *Aerror=1; // flag
4162  flxflg=1;
4163  OnX6();
4164  *Aerror=0;
4165  if(rsize==0) answ=IDNO; else answ=IDYES;
4166  break;
4167  }
4168  flxflg=0;
4169 
4170  if(*zeile=='#') // find #satznr
4171  {
4172  answ=IDYES;
4173  irn=atol(zeile+1);
4174 
4175  if(!irn) irn=Bank->InMaxRecNr(); // find #0: last rec
4176  int r=dbFetch(irn,0);
4177  if(r==-2) answ=IDCANCEL;
4178  else if(!Rec->rFi) answ=IDNO; // Satznr unbesetzt
4179  else if(*cmd=='F')
4180  { OnDBP(); setFldList(Rec); rwu=0; }
4181 // else rwu=-2;
4182  irn=Rec->rNr;
4183 // flxflg=1;
4184 // sprintf(Aerror,"answ=%d, zeile=%s, no=%d, canc=%d, rFi=%d",answ,zeile,IDNO,IDCANCEL,Rec->rFi); MessageBox(Aerror); *Aerror=0;
4185  break;
4186  }
4187  else if(*zeile!='+') // real find command
4188  { int r; char *rest;
4189  if((r=WhichRestr(Bank,zeile))>-1) // es ist ein Restr.Befehl
4190  { // restri = rpovalue r=r/s p=position o ="<>!="
4191  int j=3; while(zeile[j]==' ') ++j;
4192  strncpy(restri,Bank->restrics+r*6,2); strncpy(restri+2,zeile+j,60);
4193  rest=strchr(zeile+j,' ');
4194  if(!rest)
4195  {
4196  if(!rsize || !rsF) { answ=IDNO; break; }
4197  int r=0; int j=0;
4198  fseek(rsF,4L,0); // file starts at 4
4199  readRes2(); // read numbers into result
4200  while(r<rsize)
4201  { if(Bank->InRestri(result[r],restri)) result[j++]=result[r]; ++r; }
4202  if(j==rsize) answ=IDNO;
4203  else
4204  {
4205  rsize=res=j;
4206  rwu=-2;
4207  saveRset();
4208  }
4209  break;
4210  }
4211  else { Rmod=1; strcpy(zeile,rest+1); if((rest=strchr(restri,' '))!=0) *rest=0; }
4212  }
4213  if(*zeile!='*') // choose * heisst Auswahl aus momentaner Erg.Menge
4214  {
4215  if(*cmd!='î') {if(rsF) fclose(rsF); rsF=0; rsize=0; } // nicht bei f1nd
4216  codflag=0; // ANSI->ASCII verhindern Mehrfachspatien eliminieren!
4217  char *z=zeile+5000;
4218  int i=0;
4219  while((z[i]=zeile[i]))
4220  if(z[i]==' ') { if(zeile[i+1]==' ') z[i++]=7; else ++i; } else ++i;
4221  strcpy(srTerm,z);
4222  res = NewSearch(z,result,MAXR,7); // 7 statt blank: sonst Mehrfachspat. durch Parser vernichtet!
4223  }
4224 // Bank->E3Coding((CHAR *)zeile,0,0);
4225  codflag=1;
4226  } // Suche in Erg.Menge mit find +
4227  else
4228  { sprintf(zeile,",%s",inpu);
4229  if(*cmd=='f') flxflg=1;
4230  res=SRRP(zeile);
4231  }
4232  }
4233  else res=anzFam; // fam
4234  if(*Aerror || !res) { yex=IDNO; if(*cmd!='î') rsize=0; } // bei f1nd Erg.Menge nicht aendern!
4235  else if(res>0)
4236  {
4237  if(*cmd==3) { flxflg=1; rwu=0; }
4238  // get 1st rec and display
4239  if(*cmd=='F') { yex=IDNO; rwu=0; if(res==1) dbFetch(irn=result[0],1); }
4240  if(*cmd=='f' || *cmd=='î') { dbFetch(irn=result[0],0); rwu=-2; answ=IDYES; }
4241  if(!flxflg || *cmd==3 || *cmd==19)
4242  {
4243  if(*inpu!='+' && *cmd!='î')
4244  { int x=xmod; rsize=res; if(*cmd==19) { xmod=0; strcat(zeile,"(fam)"); } saveRset(); res=rsize; xmod=x; } // Fam: Expansion verhindern!
4245  }
4246 //if(res>1) { if(*inpu!='+') saveRset(); } // do result set
4247 // else rsn=1;
4248  bON=rwu=0;
4249  flxflg=1;
4250  if(*cmd==3)
4251  {
4252  if(rn3) { answ=IDYES; Bank->InSTL(rn3,(CHAR *)inpu); }
4253  else { answ=IDCANCEL; *inpu=0; }
4254  }
4255  }
4256  if(*cmd!='î') rsize=res; else if(!res) answ=IDNO;
4257  break;
4258  }
4259 
4260  case 125: // input n : set input file #
4261  {
4262  if(cmd[iex]) strcpy(inpu,cmd+iex);
4263  int n=atoi(inpu); *inpu=0;
4264  if(n>0 && n<256 && accu>1) Bank->inputFi=inputFi=n;
4265  break;
4266  }
4267  case 27: // STOP: abrupt end
4268  {
4269  *Aerror=1;
4270  if(cmd[iex]) strcpy(inpu,cmd+iex);
4271  if(strlen(inpu)>2) strcpy(rpTerm,inpu); else *rpTerm=0;
4272  flxflg=0;
4273 // Dateien schliessen, denn der betr. Pkt in OnCancelX() wird nicht erreicht:
4274  if(rsF && rsF!=rs1 && rsF!=rs2) fclose(rsF); rsF=0;
4275  if(atF) fclose(atF);
4276  if(edF) fclose(edF);
4277  if(nwF) fclose(nwF);
4278  OnCancelX(); // ENDE
4279 // DestroyWindow();
4280  if(*rpTerm) callProg(rpTerm,"C"); // STOP prog
4281  exit(9);
4282  break;
4283  }
4284 
4285  case 'ú': // sort inpu content
4286  { CHAR *sr, *tr, *gz, *dd; int an=0; int am=0;
4287  char md='a'; // asc / desc
4288  int pos=0; // where to begin
4289  // src + trg for string transfer
4290  if(cmd[iex])
4291  { md=cmd[iex];
4292  if(cmd[iex+1]) pos=atoi(cmd+iex+1);
4293  }
4294  inpu[4000000]=0; // Nur zur Sicherheit
4295  sr=(CHAR *)inpu; tr=(CHAR *)ex;
4296  if(sr[strlen(sr)-1]>13) strcat(sr,"\r\n"); // last line lacks 13 10
4297  // 0. copy inpu -> ex
4298  // 1. Identify the line addresses in ay[]
4299  while(1)
4300  {
4301  gz=wr; dd=sr;
4302  ay[an++]=tr; sr+=pos;
4303  // nxt str ad -> gz
4304  while((*gz++=*sr++)>13 || gz[-1]==9);
4305  *gz=0; // end of coded line
4306  // coding this line
4307  xcode((char *)tr,(char *)wr,0); tr+=strlen(tr)+1;
4308  sr=dd;
4309  // add the uncoded line
4310  while((*tr++=*sr++)>13 || sr[-1]==9); while(*sr && *sr<14) *tr++=*sr++;
4311  if(!*sr) { *tr=0; break; }
4312  if(an>7990) {MessageBox(uif[143]); break; }
4313  }
4314  // 2. now sort we have an lines
4315  if(md=='a')
4316  qsort(ay, an, sizeof(CHAR *),Strcmp);
4317  else qsort(ay, an, sizeof(CHAR *),nStrcmp);
4318  // 3. copy ex -> inpu
4319  tr=(CHAR *)inpu;
4320  while(am<an)
4321  {
4322  sr=ay[am]+strlen(ay[am])+1; ++am;
4323  while((*tr++=*sr++)>13 || tr[-1]==9); while(*sr && (*tr++=*sr++)<14); --tr;
4324  }
4325  *tr=0;
4326  }
4327  break;
4328 
4329  case 'é': // sleep/slice
4330  {
4331  char *flx; flx=cmd+iex;
4332  if(!*flx) flx=inpu;
4333  int z=atoi(flx);
4334  if(!z) z=1;
4335  if((flx=strchr(flx,'='))!=0) // slice n=job
4336  {
4337  flx+=1;
4338  strcpy(timerflex,flx);
4339  SetTimer(1,z,TimerProc);
4340  }
4341  else // sleep n (milliseconds)
4342  {
4343  m_enter.GetWindowText(inpu+40000,2000); // Schreibfeld sichern
4344  if(!z) z=1000;
4345 // CWaitCursor cc; //Sanduhr
4346  counter(1,2);
4347 // m_enter.SetWindowText(""); m_enter.RedrawWindow();
4348  m_rdisp.SendMessage(WM_PAINT); // Bild aktualisieren
4349  _sleep(z);
4350  counter(0,2);
4351 // m_enter.SetWindowText("");
4352  m_enter.SetWindowText(inpu+40000); // Schreibfeld wiederherstellen
4353  }
4354  break;
4355  }
4356  case 7: // jump to #-x in Dsp
4357  case 8: // deposit. same, but no real display, copy to inpu!
4358  {
4359  int af=0;
4360  int D=dim; dim=1;
4361  if(cmd[iex]=='+') { af=2; strcpy(cmd+iex,cmd+iex+1); }
4362  else if(cmd[iex]=='p' && (cmd[iex+1]==' ' || !cmd[iex+1])) // disp p nnn
4363  {
4364  if(cmd[iex+1]) strcpy(dspN,cmd+iex+2);
4365  else strcpy(dspN,inpu);
4366  delete Dsp;
4367  Dsp = new EXET(dspN,Cfg,0,dbDir); // load dspN param file
4368  if(*Aerror || !Dsp) MessageBox(Aerror);
4369  else
4370  { Dsp->ExOutf(putBuff);
4371 
4372  if(Dsp->etb[0][132]==132) // o.apt nicht enthalten
4373  {
4374  Dsp->E2Exet("o",Cfg,2); // load o.xpt (frueher o.apt)
4375  *Aerror=0;
4376  }
4377 
4378  dim=1;
4379  OnDBP();
4380  }
4381  break;
4382  }
4383  else if(cmd[iex]=='r') // disp reserve: sho #u variables in display
4384  {
4385  int i=0; *ex=0;
4386  strcpy((char *)ex,listhead);
4387  while(i<fri)
4388  {
4389  strcpy(wr,fa[i]);
4390  wr[256]=0; stresc((char *)wr); // cut at pos 256 to prevent crash in stresc()
4391  strcat(ex,wr); strcat(ex,"\\par ");
4392  ++i;
4393  }
4394  Bank->E3Coding((CHAR *)ex,0,0); // srch term ASCII->ANSI
4395  rtfpos=0;
4396  hmod=2; // for OnBack: to re-display rec
4397  m_rdisp.StreamIn(SF_RTF,Rex); // move ex[] to rtf display
4398  *ex=0;
4399  break;
4400  }
4401  else if(cmd[iex]=='e' || cmd[iex]=='s') // disp sets / ergeb
4402  {
4403  int j,i=1; *ex=0;
4404  strcpy((char *)ex,listhead);
4405  while(i<=rss)
4406  {
4407  j=UtPfind(i+3000);
4408  if(j!=-1)
4409  { strcat(ex,(char *)pa[j]+1); strcat(ex,"\\par "); }
4410  ++i;
4411  }
4412  Bank->E3Coding((CHAR *)ex,0,0); // srch term ASCII->ANSI
4413  rtfpos=0;
4414  hmod=2; // for OnBack: to re-display rec
4415  m_rdisp.StreamIn(SF_RTF,Rex); // move ex[] to rtf display
4416  *ex=0;
4417  break;
4418  }
4419  else if(cmd[iex]=='l') // disp list
4420  { ResList(0,0,rsize); m_rdisp.SetFocus(); m_rdisp.SetSel(1,1); break; }
4421  else if(cmd[iex]=='f') // disp flip-pos
4422  {
4423  if(isdigit(cmd[iex+1])) flipline=atoi(cmd+iex+1);
4424  m_rdisp.SetSel(0L,0L);
4425  m_rdisp.LineScroll((flipline-15<0)?0:flipline-10);
4426  break;
4427  }
4428  else if(cmd[iex]=='z') // disp zeile
4429  { int lg;
4430  if(isdigit(cmd[iex+1])) lg=atoi(cmd+iex+1); else lg=atoi(inpu);
4431  m_rdisp.SetSel(0L,0L);
4432  m_rdisp.LineScroll((lg<0)?0:lg-1);
4433  break;
4434  }
4435 
4436  if(cmd[iex]==34) ++iex; // disp "xybc" : execute param at label #-x
4437  strcpy(zeile,"#u1 ");
4438  strcpy(zeile+Cfg->skt,cmd+iex+1);
4439  if(zeile[strlen(zeile)-1]==34) zeile[strlen(zeile)-1]=0;
4440  Dsp->ch1=(CHAR *)zeile; // #u1
4441  if(*cmd==7) OnDBP(cmd+iex,0,af); else { *ex=0; OnDBP(cmd+iex,1); }
4442  if(*cmd==8) strcpy(inpu,ex);
4443  dim=D;
4444  break;
4445  }
4446 
4447  case 'ó': // dir pattern, z.B. dir *.alg
4448  {
4449  if(cmd[iex]) strcpy(inpu,cmd+iex);
4450  if(*inpu=='*') { *getzeil='*'; strcpy(getzeil+1,inpu); strcpy(inpu,getzeil); }
4451  iN=ffil(inpu,inpu); // file names to inpu, separated by code 20
4452  break;
4453  }
4454 
4455  case 'g': // get
4456  {
4457  answ=IDYES;
4458  if(cmd[iex]=='e') // get env
4459  {
4460  char *e;
4461  while(cmd[iex] && cmd[iex++]!=' ');
4462  if(!cmd[iex]) strcpy(cmd+iex,inpu);
4463  e=getenv(cmd+iex);
4464  if(!e) answ=IDNO;
4465  else strcpy(inpu,e);
4466  break;
4467  }
4468  if(cmd[iex]=='p') // get phr / get pid
4469  {
4470  if(cmd[iex+1]=='i') // pid
4471  {
4472  sprintf(inpu,"%d",pid);
4473  break;
4474  }
4475  while(cmd[iex] && cmd[iex++]!=' ') ;
4476  if(!cmd[iex]) strcpy(cmd+iex,inpu);
4477  strcpy(zeile,phrN);
4478  if(cmd[iex]) strcpy(phrN,cmd+iex); else strcpy(phrN,inpu);
4479  aph_read();
4480  strcpy(phrN,zeile);
4481  break;
4482  }
4483  if(cmd[iex]=='v') // get view
4484  {
4485  if(!vwF) { answ=IDCANCEL; *inpu=0; break; }
4486  while(cmd[iex] && cmd[iex++]!=' ') ;
4487  if(!cmd[iex]) strcpy(cmd+iex,inpu);
4488  if(cmd[iex]) vwn=atoi(cmd+iex); else vwn=atoi(inpu);
4489  if(vwn>vwz) { answ=IDNO; *inpu=0; break; }
4490  fseek(vwF,(long)vwn*vwl,0);
4491  fgets(inpu,vwl,vwF);
4492  inpu[vwl-2]=0; // help or flx ?
4493  break;
4494  }
4495  if(cmd[iex]=='I') // get IURL, file content goes to inpu
4496  {
4497  int r;
4498  answ=IDYES;
4499  r=InterGetFile(cmd+iex+1,inpu,255000);
4500 // ACHTUNG: FLEX wird u.U. abrupt beendet, wenn die Datei nicht existiert!!!
4501  if(r==1) answ=IDNO;
4502  if(r==-1) answ=IDCANCEL;
4503  break;
4504  }
4505  if(cmd[iex]=='a') // get adr nnn : addr of rec nnn
4506  {
4507  while(cmd[iex] && cmd[iex++]!=' ') ;
4508  if(!cmd[iex]) strcpy(cmd+iex,inpu);
4509  RECNR rn=atol(cmd+iex);
4510  Bac->rNr=Rec->rNr;
4511  int ra=Bank->AbGet(rn,Bac,2);
4512  if(ra==-2) strcpy(inpu,"too large");
4513  else if(!ra || rn<1L) strcpy(inpu,"no recnr");
4514  else if(ra==-3 || ra==-4) strcpy(inpu,"TBL not accessible");
4515  else if(ra==-1) strcpy(inpu,"unused");
4516  else if(*Aerror) { strcpy(inpu,Aerror); *Aerror=0; }
4517  else sprintf(inpu,"%d / %ld",Bac->rFi,Bac->rOf);
4518  break;
4519  }
4520 // get from file
4521  if(Fty!=2 && !xF) { answ=IDNO; break; }
4522  *w=0;
4523  if(cmd[iex]=='#') // get #nnn
4524  {
4525  if(!cmd[iex+1]) strcpy(cmd+iex+1,inpu);
4526  sprintf((char *)w,"%s",cmd+iex);
4527  if(strlen(w)<Cfg->skt) { strcat(w," "); w[Cfg->skt]=0; }
4528  }
4529  // now w is the point where to put stuff from the file
4530  if(Fty==2)
4531  {
4532  if(!Url || InterGet((char *)(w+strlen(w)))==0) { Fty=0; delete Url; Cif->Close(); delete Cif; answ=IDCANCEL; }
4533  }
4534  else if(readLine(xF,w+strlen(w))==0)
4535  { fclose(xF); xF=0; answ=IDCANCEL; counter(0,100); *w=0;}
4536  else counter(ftell(xF),fsz);
4537  // so we got sthg - what to do with it?
4538  if(cmd[iex]=='x') // get x : parameter line, comment set off by //##
4539  {
4540  while(*w && w[strlen(w)-1]<14) w[strlen(w)-1]=0;
4541  remcom(w);
4542  if(cmd[iex+1]=='+') strcat(inpu,(char *)w);
4543  else strcpy(inpu,(char *)w);
4544  }
4545  else if(cmd[iex]=='#') // get #nnn
4546  {
4547  UtRemsp(w);
4548  if(cmod=='0') Bank->E3Coding(w,0,1); // ANSI -> ASCII $$060210
4549 
4550  m_enter.SetWindowText((char *)w);
4551  fowi=2;
4552  int li=limo;
4553  if(limo!=1 && limo!=2) limo=1;
4554 // sprintf(Aerror,"FLEX,w=%s",(char *)w); MessageBox(Aerror);
4555  ReadyW();
4556  m_enter.SetWindowText("");
4557  limo=li;
4558  fowi=1;
4559  }
4560  else { // normales get or get iV or get +iV, Text steht in w
4561 // int j=strlen(w)-1;
4562 // while(j>-1 && w[j]<14) w[j--]=' '; // LineFeed am Ende durch Space ersetzen
4563  if(cmd[iex]=='+') strcat(inpu,(char *)w);
4564  else