Ctrl-C in Construct (workaround)
Posted in 1993
Topics: Stored Procedures & SPL, Connectivity: ESQL/C, 4GL & Embedded SQL
I have already a workaround, based on a information from INFORMIX, to the following problem: > When I press the interrupt key in a construct, > when the window is closed i get the following error: > > Program stopped at "bug.4gl", line number ... > FORMS statement error number -1141. > Cannot close window with active INPUT, DISPLAY ARRAY > or MENU statement. > > Follows a small program to demonstrate the problem. > > {--------------------------------------------} > main > define > s char(256) > > defer interrupt > > open window w at 2, 2 with form "bug" attribute ( border ) > > construct by name s on a > > close window w > end main > {--------------------------------------------} > > Is this a known bug ? > Is there any workaround ? > > The environment is: > Operating System > OSF1 T1.3 80.2 alpha > INFORMIX-4GL Version 4.10.UE2 > INFORMIX-OnLine Version 5.00.UD1 The idea is to add C code to the generated one, to decrement the ucount field of the current window (see definition of _EFwindow in $INFORMIXDIR/incl/sqlfm.h), when someone presses control-c in a construct. We have to know which is the current window. To do so, we use a stack which is pushed when opening a window and poped when it is closed (it`s not really a stack, because we can close a window which were not the last to be open). The top of the stack is always the current window. After a construct (when C function _efconclean() is called), if the ucount field has the same value (hapenns when someone presses control-c), it should be decremented. This solution worked well in the environment above. I`m not sure it will also work in other environments. To implement this solution, and to be completely transparent, do the following: /* Create another script (or alter the original) to compile the 4GL files. * The script should be something like that: */ /*************************** BEGINING OF FILE *********************/ FGLC=${INFORMIXDIR=/usr/informix}/lib/fglc FGLC2=${INFORMIXDIR=/usr/informix}/lib/fglc2 STAT=0 TEMP=0 DOEXIT=0 A= ANSIFLG= ANYFLG= BFLG= INFDIR=${INFORMIXDIR=/usr/informix} patchosf() { echo "::: (test construct)" INFDIR=${INFORMIXDIR=/usr/informix} cc -I$INFDIR/incl -P $FBASE.c FBASEPP=`basename $FBASE` awk -f $TOOLS/bin/patchosf.awk $FBASEPP.i > $FBASE.c rm $FBASEPP.i } for F do case $F in -a ) BFLG=$F ;; -ansi ) ANSIFLG=$F ;; -anyerr ) ANYFLG=$F ;; *.4gl ) FBASE=`basename $F .4gl` $FGLC $BFLG $ANSIFLG $ANYFLG $F TEMP=$? if [ $TEMP -eq 0 -o $TEMP -eq 6 ] then $FGLC2 -4GL $FBASE.ec patchosf TEMP=$? fi A="$A $FBASE.c" ;; *.ec ) FBASE=`basename $F .ec` $FGLC2 -4GL $ANSIFLG $F patchosf TEMP=$? A="$A $FBASE.c" ;; *.c ) FBASE=`dirname $F`/`basename $F .c` patchosf TEMP=$? A="$A $F" ;; -e ) DOEXIT=1; ;; -V ) $FGLC $F exit $STAT ;; * ) A="$A $F" ;; esac if [ $TEMP -ne 0 -a $STAT -eq 0 ] then STAT=$TEMP fi done if [ $DOEXIT -eq 0 -a $STAT -eq 0 ] then INFDIR=${INFORMIXDIR=/usr/informix} exec cc -I$INFDIR/incl $A $INFDIR/lib/lib4gl.a \\ $INFDIR/lib/libnforms.a $INFDIR/lib/libfesql.a \\ $INFDIR/lib/libosf.a -lbsd -ltermlib else exit $STAT fi /*************************** END OF FILE ***************************/ /* * $INFDIR/lib/libosf.a is a librarie, created with the following C code: */ /*************************** BEGINING OF FILE *********************/ #include <stdio.h> #include <sqlfm.h> #define MAXWIN 40 /** Max open windows **/ static _EFwindow *arrWin[MAXWIN] ; static int nWin ; void PushWindow( _EFwindow *TheWin ) { extern int nWin ; extern _EFwindow *arrWin[] ; arrWin[nWin++] = TheWin ; } void PopWindow( _EFwindow *TheWin ) { extern int nWin ; extern _EFwindow *arrWin[] ; int i, k ; for(i = 0 ; i < nWin && arrWin[i] != TheWin ; i++) ; if (i >= nWin) /* Window doesn't exist */ return ; nWin -- ; for( k = i ; k < nWin ; k++) arrWin[k] = arrWin[k + 1] ; arrWin[nWin] = NULL ; } _EFwindow *TopWindow() { extern int nWin ; extern _EFwindow *arrWin[] ; if ( nWin ) return arrWin[nWin - 1] ; else return NULL ; } /*************************** END OF FILE ***************************/ /* * $TOOLS/bin/patchosf.awk is the following awk file: */ /*************************** BEGINING OF FILE *********************/ /^[ \\t]*_efconclean\\([^;]*;[ \\t]*$/ \\ { printf( "{\\n") printf( "\\t unsigned long theCount;\\n") printf( "\\t if( TopWindow() ) \\n") printf( "\\t\\t\\t theCount = ((_EFwindow *)TopWindow())->ucount;\\n") printf( "\\t %s\\n",$0) printf( "\\t if( TopWindow() && ") printf( " theCount == ((_EFwindow *)TopWindow())->ucount)\\n") printf( "\\t\\t\\t ((_EFwindow *)TopWindow())->ucount--;\\n") printf( "}\\n") next } /^[ \\t]*_efwclose\\([^;]*;[ \\t]*$/ \\ { n = index($0,"&") if( n > 0 ) { i = n + 1 while ( substr($0,i,1) == "(") i++; n = index(substr($0,i,length()-i+1),")") if ( n > 0) { j = n - 1 theWindow = substr($0,i,j) printf( "PopWindow(%s);\\n", theWindow) } } print next } /./ { print } /^[ \\t]*\\}[ \\t]*_EFwindow[ \\t]*;[ \\t]*$/ \\ { print " _EFwindow * TopWindow(); " next } /^[ \\t]*_efiwopen\\([^;]*;[ \\t]*$/ \\ { n = index($0,"&") if( n > 0 ) { i = n + 1 n = index( substr($0,i,length()-i+1), ",") if ( n > 0) { theWindow = substr($0,i,n - 1) printf( "PushWindow(%s);\\n", theWindow) } } next } /*************************** END OF FILE ***************************/
Related threads
- Re: CLOSE WINDOW after CONSTRUCT problem w/interrupt
- Re: 4GL 4.10 and Interrupting a Construct Statement
- Solution for CLOSE WINDOW after CONSTRUCT problem after <interrupt>
- Bug #35964 (was: FORMS error 1141)
- CPU consumption and table size