// // Driver Odbc // void * sqlLiteScroll(struct OBJ *objCalled,EN_MESSAGE cmd,LONG info,CHAR *str) { static struct WINSCR rit,*PtScr; EH_DISPEXT *psExt; S_SCR_INFO * psSI,sSqlInfo; INT a;//,b; // INT ptClient; // SQLRETURN sqlReturn; // // Inizializzazione // if (_local.bReset) { _local.lstScr=lstCreate(sizeof(S_SCR_INFO)); FTIME_on(_SqlThreadRefresh,1); _local.bReset=false; } // Oggetto buono ? if ((objCalled->tipo!=OW_SCR)&&(objCalled->tipo!=OW_SCRDB)) return 0; psSI=objCalled->pOther; if (cmd==WS_INF) return &psSI->ws; switch (cmd) { // ----------------------------------- // APERTURA DEL DRIVER | // ----------------------------------- case WS_CREATE: //break; #ifdef OS_DEBUG printf("OdbcScroll: Create" CRLF); #endif _(sSqlInfo); objCalled->pOther=lstPush(_local.lstScr,&sSqlInfo); psSI=objCalled->pOther; psSI->ObjClient=objCalled; psSI->ObjClient->bFreeze=TRUE; // Blocco la gestione dell'oggetto psSI->bDrawLineDiv=TRUE; #ifdef EH_SQL_SQLITE psSI->enPlatform=_SQL_SQLITE; #endif #ifdef EH_SQL_MYSQL psSI->enPlatform=_SQL_MYSQL; #endif // // Alla prima chiamata creo thread e "finestrame" necessario // // Tecnologia sqlLite // - La connessione deve essere inizializzata // if (!psSI->hThread) { memset(&psSI->csSqdStruct,0,sizeof(CRITICAL_SECTION)); memset(&psSI->csSqdQuery,0,sizeof(CRITICAL_SECTION)); InitializeCriticalSection(&psSI->csSqdStruct); InitializeCriticalSection(&psSI->csSqdQuery); /* // // Alloco lo stantment clone ( Si libererà con WS_DESTROY) // sqlReturn=SQLAllocHandle(SQL_HANDLE_STMT, sOdbcSection.hConn, &psSI->hStmtScroll); if (sqlReturn!=SQL_SUCCESS&&sqlReturn!=SQL_SUCCESS_WITH_INFO) ehExit("OdbcScroll:hStmt Clone impossible %d",sqlReturn); // Bho ? SQLSetStmtAttr(psSI->hStmtScroll, SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_READ_ONLY, 0); sqlReturn=SQLSetStmtAttr(psSI->hStmtScroll, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE , 0); if (sqlReturn==SQL_ERROR) // Altro metodo { sqlReturn=SQLSetStmtAttr( psSI->hStmtScroll,SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_STATIC, 0); if (sqlReturn==SQL_ERROR) win_infoarg("errore in assegnazione cursore"); sqlReturn=SQLSetStmtAttr( psSI->hStmtScroll, SQL_ATTR_USE_BOOKMARKS, (SQLPOINTER) SQL_UB_VARIABLE, 0); if (sqlReturn==SQL_ERROR) win_infoarg("SQL_ATTR_USE_BOOKMARKS"); } //sprintf(szCursor,"SQD%d",ptClient); //SQLTRY(SQL_HANDLE_STMT,"SQD->",psSI->hStmtScroll,SQLSetCursorName(psSI->hStmtScroll, szCursor, SQL_NTS)); //SQLTRY("ASYNC",psSI->hStmtScroll,SQLSetStmtAttr(psSI->hStmtScroll, SQL_ATTR_ASYNC_ENABLE, (SQLPOINTER) SQL_ASYNC_ENABLE_ON , 0)); // // 4) Creo il Thread (SQLExecuteThread) per l'elaborazione delle query // */ for (a=0;a<ESQL_MAXEVENTLOAD;a++) psSI->arhEvent[a]=CreateEvent(NULL,true,FALSE,NULL); psSI->hThread = CreateThread(NULL, 0, _sqlExecuteThread, (LPDWORD) psSI, 0, &psSI->dwThread); psSI->bAutoRowSelect=TRUE; // <-- 2010 - Inserito auto select in partenza SetThreadPriority(psSI->hThread,THREAD_PRIORITY_NORMAL); } break; case WS_OPEN: // // Inizializzazione della finestra // if (info<3) {ehExit("Field ? " __FUNCTION__);} psSI->ws.numcam=info;// Assegna il numero di campi da visualizzare psSI->ws.selez=-1; psSI->ws.maxcam=0; psSI->ObjClient->tipo=OW_SCR; psSI->lRowsTotal=0; psSI->fChanged=0; psSI->ObjClient->bFreeze=FALSE; if (psSI->funcNotify) psSI->funcNotify(_adaptor(objCalled,WS_OPEN,0,NULL,NULL));//objCalled,NULL,0,NULL,WS_OPEN,NULL,NULL); psSI->ws.bExtSelection=TRUE; // Gestione esterna della selezione psSI->ws.fNoBlankLine=TRUE; case WS_LOAD: break; // ----------------------------------- // Richiesta di refresh // ----------------------------------- case WS_RELOAD: if (info) _queryExecute(psSI,__LINE__); else _fetch(psSI); return NULL; // Non serve stampare // ----------------------------------- // WS_CLOSE IL DRIVER | // ----------------------------------- case WS_CLOSE: sqlLiteScroll(objCalled,WS_PROCESS,STOP,NULL); // Chiedo di fermare il processo in corso psSI->ObjClient->bFreeze=true; if (psSI->funcNotify) (psSI->funcNotify)(_adaptor(objCalled,WS_CLOSE,0,NULL,NULL)); break; // ----------------------------------- // CHIUSURA DEFINITIVA DEL GESTORE (chiamato in obj_close()); // ----------------------------------- case WS_DESTROY: // // Notifico la chiusura alla funzione esterna // if (psSI->funcNotify) (psSI->funcNotify)(_adaptor(objCalled,WS_DESTROY,0,NULL,NULL)); // Fermo il Thread SetEvent(psSI->arhEvent[ESQL_STOP]); // Segnalo che siamo in chiusura if (WaitForSingleObject(psSI->hThread,5000)) { //_dx_(0,20,"Entro qui"); //SQLFetchScroll(psSI->hStmtScroll,SQL_FETCH_FIRST,0); //SQLFreeHandle(SQL_HANDLE_STMT,psSI->hStmtScroll); psSI->hStmtScroll=0; //_dx_(0,40,"Terminate %d",TerminateThread(psSI->hThread,0)); } /* if (psSI->hStmtScroll) {SQLFreeHandle(SQL_HANDLE_STMT,psSI->hStmtScroll); psSI->hStmtScroll=0;} if (psSI->rsSet) {odbc_QueryResultDestroy(psSI->rsSet); ehFree(psSI->rsSet);} psSI->rsSet=NULL; // Libero la memoria usata per la Query ehFreePtr(&psSI->pQueryActive); ehFreePtr(&psSI->pszQueryCount); ehFreePtr(&psSI->pLastErrorText); // Libero la memoria usata per la WhereAdd ehFreePtr(&psSI->pQuerySelect); ehFreePtr(&psSI->pszKeyCode); ARDestroy(psSI->arKeyCodeFld); ehFreePtr(&psSI->pCodeFocused); ehFreePtr(&psSI->pCodeSelected); ehFreePtr(&psSI->pCodeReturn); // Libero gli Handle degli eventi for (a=0;a<ESQL_MAXEVENTLOAD;a++) CloseHandle(psSI->arhEvent[a]); // 1.2.3. Liberi tutti !! DeleteCriticalSection(&psSI->csSqdStruct); DeleteCriticalSection(&psSI->csSqdQuery); // Azzero la struttura di riferimento memset(psSI,0,sizeof(S_SCR_INFO)); */ { EH_LST_I * psi; psi=lstSearch(_local.lstScr,objCalled->pOther); lstRemoveI(_local.lstScr,psi); } ehFreePtr(&objCalled->pOther); break; // ----------------------------------- // PRESSIONE DI UN TASTO/MOUSE | // ----------------------------------- case WS_KEYPRESS: if (key_press2(KEY_F9)) {strcpy(str,"ESC:F9"); break;} if (psSI->funcNotify) (psSI->funcNotify)(_adaptor(objCalled,cmd,info,str,NULL)); break; // ----------------------------------- // SETTA SELEZIONE RECORD | // ----------------------------------- case WS_SEL: if (!psSI->funcNotify) break;//ehExit(SdbDriver32 ":No ext/disp function"); // if (!psSI->rsSet) break; // printf("%d",psSI->rsSet->iCurrentRow); //if (psSI->ws.selez==-1) break; break; // ------------------------------------- // SETTA L'OFFSET (Solo Modo O_SCROLL | // ------------------------------------- case WS_OFF: break; // ------------------------------------- // // ------------------------------------- case WS_PTREC : // Restituisce pt alla chiave selezionata case WS_GET_SELECTED: _(rit); rit.record=-1; if (strEmpty(psSI->pszKeyCode)) {efx2(); return NULL;} /* // // Selezione in scroll // if (psSI->rsSet&&psSI->ws.selez>-1) { psSI->rsSet->iCurrentRow=psSI->ws.selez; if (strEmpty(psSI->pszKeyCode)) ehExit("%s:%d manca assegnazione pszKeyCode",__FILE__,__LINE__); _keyCodeBuilder(&psSI->pCodeReturn,psSI); rit.record=psSI->ws.selez; rit.keypt=psSI->pCodeReturn; if (psSI->bAutoRowSelect) { strAssign(&psSI->pCodeSelected,psSI->pCodeReturn); InvalidateRect(objCalled->hWnd,NULL,FALSE); } } // // Pre-selezione (non entrao in scroll // else if (!strEmpty(psSI->pCodeSelected)) { rit.record=psSI->ws.selez; rit.keypt=psSI->pCodeSelected; } if (cmd==WS_GET_SELECTED) return retCreate(_ALFA,rit.record,rit.keypt); */ return &rit; // ------------------------------------- // RITORNA Selez ?????????? | // ------------------------------------- case WS_REALGET: break; // ------------------------------------- // Refresh a ON | // ------------------------------------- case WS_REFON : psSI->ws.refre=ON; break; case WS_REFOFF : psSI->ws.refre=OFF; break; case WS_PROCESS: if (info==STOP&&!str) { // SQLCancel(psSI->hStmtScroll); // Cancello il processo nello stantment printf("> cancellare processo in corso"); EnterCriticalSection(&psSI->csSqdStruct); psSI->fBreak=true; LeaveCriticalSection(&psSI->csSqdStruct); while (TRUE) {if (!psSI->fInProcess) break; else Sleep(50);} //win_infoarg("SQL stop"); } // Controllo se l'elaborazione è in corso if ((info==0)&&(*str=='?')) { if (psSI->fInProcess) return "!"; else return NULL; } break; // // Chiedo di cambiare il la Where di ricerca // case WS_SETFILTER: EnterCriticalSection(&psSI->csSqdStruct); ehFreePtr(&psSI->pQuerySelect); psSI->pQuerySelect=strDup(str); psSI->ws.selez=-1; psSI->ws.maxcam=0; psSI->lRowsReady=0; psSI->lRowsTotal=0; LeaveCriticalSection(&psSI->csSqdStruct); if (info) { InvalidateRect(objCalled->hWnd,NULL,TRUE); _message(psSI,TRUE,"Attendere\nRichiesta al server ..."); OsEventLoop(5); } psSI->fQueryToExecute=true; // _queryExecute(psSI,__LINE__); // Me ne arriva uno dopo break; case WS_SETFLAG: objCalled->pOtherEx=str; // Assegno un puntatore esterno if (psSI->funcNotify) (psSI->funcNotify)(_adaptor(objCalled,WS_SETFLAG,info,NULL,NULL)); break; // ------------------------------------- // Richiesta di Stampa dei Dati | // ------------------------------------- case WS_DISPLAY : // Richiesta buffer psExt=(EH_DISPEXT *) str; if (!psSI->funcNotify) { Tboxp( psExt->rClientArea.left, psExt->rClientArea.top, psExt->rClientArea.right, psExt->rClientArea.bottom-1, RGB(255,128,0),SET); // arError=ARCreate(psSI->pLastErrorText,"\n",&iRow); dispf(psExt->px+1,psExt->py+1,RGB(255,255,255),-1,STYLE_NORMAL,"SMALL F",3,"-Not func for Display-"); break; } // // Richiesta di stampa del titolo // if (psExt->ncam==-10) { psSI->funcNotify(_adaptor(objCalled,WS_DISPLAY,0,psExt,NULL));//psSI->Hdb,psSI->iIndex); break; } /* if (!psSI->rsSet) { if (psSI->bSqlError) { Tboxp(psExt->px,psExt->py,psExt->px+psExt->lx-1,psExt->py+psExt->ly-1,sys.Color3DShadow,SET); if (psSI->pLastErrorText) { EH_AR arError; INT iRow; arError=ARCreate(psSI->pLastErrorText,"\n",&iRow); if (psExt->ncam<iRow) dispf(psExt->px+1,psExt->py+1,RGB(255,255,255),-1,STYLE_NORMAL,"SMALL F",3,arError[psExt->ncam]); ARDestroy(arError); } } else Tboxp(psExt->px,psExt->py,psExt->px+psExt->lx-1,psExt->py+psExt->ly-1,sys.Color3DLight,SET); break; } psExt->col1=GetSysColor(COLOR_MENUTEXT); psExt->col2=GetSysColor(COLOR_WINDOW); if (psExt->bFocus) // selezione con il mouse { psExt->col1=GetSysColor(COLOR_HIGHLIGHTTEXT); psExt->col2=ColorLum(GetSysColor(COLOR_HIGHLIGHT),30); } if (psExt->bSelected) // Selezionato fisso { psExt->col1=GetSysColor(COLOR_HIGHLIGHTTEXT); psExt->col2=GetSysColor(COLOR_HIGHLIGHT); } Tboxp(psExt->px,psExt->py,psExt->px+psExt->lx-1,psExt->py+psExt->ly-2,psExt->col2,SET); //Sleep(100); psSI->rsSet->iCurrentRow=info; psSI->rsSet->iOffset=psSI->iSQLOffset; // Non ho ancora le linee da visualizzare if (psExt->ncam>=psSI->lRowsReady|| (psSI->rsSet->iCurrentRow<psSI->iSQLOffset)|| ((psSI->rsSet->iCurrentRow-psSI->iSQLOffset)>=psSI->rsSet->iRowsLimit)) { boxBrush(psExt->px,psExt->py,psExt->rClientArea.right,psExt->rClientArea.bottom,HS_VERTICAL,sys.Color3DLight,ColorLum(sys.Color3DHighLight,-10)); Tline(psExt->px,psExt->rClientArea.bottom,psExt->rClientArea.right,psExt->rClientArea.bottom,sys.Color3DShadow,SET); break; } // RIchiedo stampa della riga psSI->funcNotify( _adaptor(objCalled,WS_DISPLAY,info,psExt, psSI->rsSet)); if (psSI->bDrawLineDiv) line(psExt->px,psExt->rClientArea.bottom,psExt->rClientArea.right,psExt->rClientArea.bottom,sys.colScrollDiv,SET); if (psExt->bFocus) { boxFocus(psExt->px,psExt->py,psExt->px+psExt->lx-1,psExt->py+psExt->ly-2); } */ break; // -------------------------------------------------------------------------- // SET della funzione esterna // -------------------------------------------------------------------------- case WS_EXTNOTIFY: psSI->funcNotify=(LRESULT (*)(EH_NOTIFYPARAMS)) str;//(INT (*)(struct OBJ *,INT ,LONG ,void *str,EH_ODBC_RS )) str; psSI->funcNotify(_adaptor(objCalled,WS_CREATE,0,NULL,NULL)); break; case WS_LINEVIEW: // psSI->ws.numcam=info; break; case WS_LINEEDIT: // psSI->ws.Enumcam=info; break; case WS_SIZE: break; case WS_MOVE: break; case WS_SETTITLE: break; case WS_CODENAME: strAssign(&psSI->pszKeyCode,str); strTrim(psSI->pszKeyCode); ARDestroy(psSI->arKeyCodeFld); psSI->arKeyCodeFld=ARCreate(psSI->pszKeyCode,"+",&psSI->iKeyCodePart); break; // // Riga in FOCUS // /* case WS_SET_ROWFOCUS: if (!str) // Dal gestore oggetti { if (info<0) {strAssign(&psSI->pCodeFocused,NULL); break;} if (psSI->pCodeName&&psSI->rsSet) { psSI->rsSet->iCurrentRow=info; psSI->rsSet->iOffset=psSI->ws.offset; // psSI->rsSet->iCurrentRow riga della query if (psSI->rsSet->iCurrentRow>=psSI->iSQLOffset&& psSI->rsSet->iCurrentRow<(psSI->iSQLOffset+psSI->lRowsReady)) { strAssign(&psSI->pCodeFocused,sql_ptr(psSI->rsSet,psSI->pCodeName)); strTrim(psSI->pCodeFocused); } else { strAssign(&psSI->pCodeFocused,NULL); // Non ho la selezione richiesta in memoria } dispxEx(0,80,"%d,%d = %s ", psSI->rsSet->iCurrentRow, psSI->iSQLOffset+psSI->lRowsReady, psSI->pCodeFocused); } return NULL; } else // Esterno { strAssign(&psSI->pCodeFocused,str); InvalidateRect(objCalled->hWnd,NULL,FALSE); } break; case WS_GET_ROWFOCUS: if (psSI->pCodeName&&psSI->pCodeFocused&&psSI->rsSet) { CHAR *p; if (info<0) return NULL; psSI->rsSet->iCurrentRow=info; psSI->rsSet->iOffset=psSI->ws.offset; p=sql_ptr(psSI->rsSet,psSI->pCodeName); strTrimRight(p); if (!strcmp(p,psSI->pCodeFocused)) break; } return NULL; */ // // Riga in SELECTED // case WS_SET_ROWSELECTED: printf("qui"); /* if (!str) // Dal gestore oggetti { if (info<0) {strAssign(&psSI->pCodeSelected,NULL); InvalidateRect(objCalled->hWnd,NULL,FALSE); break;} if (psSI->pszKeyCode&&psSI->rsSet) { psSI->rsSet->iCurrentRow=info; psSI->rsSet->iOffset=psSI->ws.offset; _keyCodeBuilder(&psSI->pCodeSelected,psSI); //if (!strEmpty(p)) break; } InvalidateRect(objCalled->hWnd,NULL,FALSE); return NULL; } else // Esterno { strAssign(&psSI->pCodeSelected,str); InvalidateRect(objCalled->hWnd,NULL,FALSE); } */ break; case WS_GET_ROWSELECTED: // // Controllo di selezione // if (psSI->pszKeyCode&&!strEmpty(psSI->pCodeSelected)&&psSI->rsSet) { CHAR * p; if (info<0) return NULL; //psSI->rsSet->iCurrent=info; p=_keyCodeBuilder(psSI,info); // Può ritornare Null in p se sto chiedendo una riga che non c'è (in fase di ingrandimento) if (!strCmp(p,psSI->pCodeSelected)) {ehFreeNN(p); break;} ehFreeNN(p); } return NULL; case WS_EVENT: /* if (!psSI->rsSet) break; psSI->rsSet->iCurrentRow=info; psSI->rsSet->iOffset=psSI->iSQLOffset; if (psSI->funcNotify) { BYTE *ptr=(BYTE *) (psSI->funcNotify)(_adaptor(objCalled,cmd,info,str,psSI->rsSet)); return ptr; } */ printf("qui"); break; case WS_BUF: break; default: /* if (psSI->funcNotify) (psSI->funcNotify)(_adaptor(objCalled,cmd,info,str,psSI->rsSet)); else printf(__FUNCTION__ "Event ? [%d][%s]" CRLF,cmd,objCalled->nome); */ break; } //PtScr=psSI->WinScr; PtScr=NULL; if (!PtScr) PtScr=&rit; return PtScr; }
docommand() { register char *p; register int i; register ADDR addr, bkaddr; struct proct *procp; char s[4]; cntval = 1; adrflg = 0; errflg = 0; if (scallf) { doscall(); setcur(1); lastcom = NOCOM; return; } if (reflag) { /* search for regular expression */ dore(); lastcom = PRCOM; return; } if (cmd == '\0') { if (integ != 0 && var[0] != '\0') { error("Invalid command (1)"); return; } if (integ != 0) { /* print line number */ ffind(integ); fprint(); lastcom = PRCOM; return; } if (var[0] != 0) { printf("Unexpected null command\n"); return; } } switch (cmd) { case 'Y': debug = !debug; break; case 'V': version(); break; case 'M': if (args[0]) { setmap(args); } else { printmap("? map", &txtmap); printmap("/ map", &datmap); } break; case 'x': printregs(); break; case 'X': printpc(); break; case 'a': if (integ) { cpstr(args, "l\n"); } else if (proc[0]) { cpall(args, "T\n"); } else { error("Bad arguments"); break; } goto setbrk; break; case 'l': setcur(1); lastcom = NOCOM; break; case 'T': prfrx(1); lastcom = NOCOM; break; case 't': prframe(); lastcom = NOCOM; break; case 'e': p = args; if (*p == '\0') { #ifndef FLEXNAMES printf("%.16s() in \"%s\"\n", curproc()->pname, curfile); #else printf("%s() in \"%s\"\n", curproc()->pname, curfile); #endif break; } while (*p != '\0') if (*p++ == '.') goto l1; /* argument is procedure name */ procp = findproc(args); if ((procp->pname[0] != '\0') && (procp->sfptr != badfile)) { finit(adrtofilep(procp->paddr)->sfilename); ffind(procp->lineno); } else printf("Can't find %s\n", args); #ifndef FLEXNAMES printf("%.16s() in \"%s\"\n", curproc()->pname, curfile); #else printf("%s() in \"%s\"\n", curproc()->pname, curfile); #endif lastcom = PRCOM; break; l1: /* argument is filename */ finit(args); printf("\"%s\"\n", curfile); lastcom = PRCOM; break; case 'p': if (integ) ffind(integ); fprint(); lastcom = PRCOM; break; case 'q': exit(0); case 'w': if (integ) ffind(integ); i = fline; fback(WINDOW/2); fprintn(WINDOW); ffind(i); lastcom = PRCOM; break; case 'Q': prdebug(); break; case 'z': if (integ) ffind(integ); fprintn(WINDOW); lastcom = PRCOM; break; case '-': fback(integ ? integ : 1); fpargs(); lastcom = PRCOM; break; case '+': fforward(integ ? integ : 1); fpargs(); lastcom = PRCOM; break; case '\n': switch (lastcom) { case PRCOM: fforward(1); fprint(); break; case DSCOM: oaddr += oincr ? oincr : typetosize(otype, WORDSIZE); printf("0x%x/ ", oaddr); dispf((ADDR) oaddr, odesc, oclass == N_RSYM ? oclass : N_GSYM, otype, 0, 0, DSP); break; case DSICOM: dot += oincr; prisploc(); dispi(dot, odesc, N_GSYM, 0, 0); break; } break; case '\004': if (!isatty(0)) exit(0); switch (lastcom) { case PRCOM: fforward(1); printf("\b"); fprintn(WINDOW); lastcom = PRCOM; break; case DSICOM: printf("\b"); for (i=0; i<WINDOW; i++) { dot += oincr; prisploc(); if (dispi(dot, odesc, N_GSYM, 0, 0) == -1) break; } break; case DSCOM: printf("\b"); for (i=0; i<WINDOW; i++) { oaddr += oincr ? oincr : typetosize(otype, WORDSIZE); printf("0x%x/ ", oaddr); if (dispf((ADDR) oaddr, odesc, oclass == N_RSYM ? oclass : N_GSYM, otype, 0, 0, DSP) == -1) break; } break; default: printf("\n"); } break; case 'r': if (args[0] == '\0') getargs(); case 'R': signo = 0; cpstr(oldargs, args); if (debug) error("calling dopcs"); if (integ) cntval = integ; if (!executing) { executing = TRUE; if (integ) cntval = integ; dopcs('r'); executing = FALSE; } if (debug) error("exiting dopcs"); bkaddr = -1; goto f1; case 'c': signo = 0; case 'C': if (proc[0] != '\0' || integ != 0) { setdot(); if (dot == -1) { error("Cannot set temporary breakpoint"); break; } dopcs('b'); bkaddr = dot; } else bkaddr = -1; integ = atoi(args); f1: if (debug) error("calling dopcs"); if (integ) cntval = integ; dopcs('c'); if (debug) error("exiting dopcs"); if (bkaddr != -1) { ADDR dotsave; dotsave = dot; dot = bkaddr; dopcs('d'); dot = dotsave; } if (!signo) printf("Breakpoint"); printf(" at\n"); setcur(1); lastcom = NOCOM; break; case 'S': case 's': signo = 0; integ = atoi(args); singstep(integ ? integ : 1, cmd); if (signo) printf("\n"); setcur(1); lastcom = NOCOM; break; case 'g': if (pid == 0 || signo) { error("Not stopped at breakpoint"); break; } setdot(); if (dot == -1) { error("Bad address"); break; } adrflg = 1; integ = atoi(args); if (integ) cntval = integ; dopcs('c'); if (!signo) printf("Breakpoint"); printf(" at\n"); setcur(1); lastcom = NOCOM; break; case 'k': if (scallx) { userpc = dot = *(ADDR *)(((ADDR)&u)+PC) = pcs; *(ADDR *)(((ADDR)&u)+FP) = fps; *(ADDR *)(((ADDR)&u)+AP) = aps; if (bkpts) bkpts->flag = flagss; scallx = 0; error("Procedure killed"); longjmp(env, 0); } else { dopcs('k'); printf("\n"); lastcom = NOCOM; break; } case 'B': prbkpt(); break; case 'b': setbrk: if (proc[0] == '\0' && integ == 0) { integ = fline; } setdot(); if (dot == -1 || dot == 0) { error("Cannot set breakpoint"); break; } dopcs('b'); s[0] = ' '; s[1] = cmd; s[2] = '\n'; s[3] = 0; s[1] = cmd; printbkpt(s, adrtoprocp(dot), dot); break; case 'd': if (proc[0] == '\0' && integ == 0) { idbkpt(); break; } setdot(); if (dot == -1) { error("Non existent breakpoint"); break; } dopcs('d'); break; case 'D': dabkpt(); error("All breakpoints deleted"); break; case 'm': addr = varaddr(proc[0] ? proc : curproc()->pname, var); printf("stopped with value %d\n", monex(addr, 'd')); setcur(1); lastcom = NOCOM; break; case '?': if (!(var[0] == '.' && var[1] == '\0')) setdot(); if (errflg) { error(errflg); break; } prisploc(); dispi(dot, args[0] ? args : "i", N_GSYM, 0, 0); lastcom = DSICOM; break; case '/': if (var[0] == '.' && var[1] == '\0') { if (integ == 0) integ = oaddr; dispf((ADDR) integ, args[0] ? args : odesc, oclass == N_RSYM ? oclass : N_GSYM, otype, 0, 0, DSP); oaddr = integ; } else if (integ && (var[0] == '\0')) { dispf((ADDR) integ, args, N_GSYM, 0, 0, 0, DSP); oaddr = integ; cpstr(odesc, args); oclass = N_GSYM; otype = 0; } else dispvar(proc, var, args); lastcom = DSCOM; break; case '=': if (var[0] == '\0') { if (proc[0]) { addr = getaddr(proc, integ); if (addr == -1) { error("Unknown address"); break; } } else addr = integ; dispf(addr, args[0] ? args : "x", 0, -1, 0, 0, DSP); } else findvar(proc, var, args[0] ? args : "x", 2); break; case '!': if (var[0] == '\0') addr = getaddr(proc, integ); else addr = varaddr(proc, var); if (addr == -1) error("Unknown variable"); else { if (number(args[0]) || eqany(args[0], ".-")) { char *p; double atof(); union { struct{ int w1, w2; } ww; double d; } dbl; p = (args[0] == '-') ? args+1 : args; for (; *p != '.' && *p != 'e'; p++) { if (!number(*p)) goto l2; } dbl.d = atof(args); putval(addr, 'd', dbl.ww.w1); if (typetodesc(sl_type,0)[0] == 'g') putval(addr+WORDSIZE, 'd', dbl.ww.w2); break; } l2: if (percentflag) *(ADDR *)(((ADDR)&u)+addr) = argvalue(args); else if (sl_class == N_RSYM && addr < 16) putreg(addr,typetodesc(sl_type,subflag)[0], argvalue(args)); else putval(addr,typetodesc(sl_type,subflag)[0], argvalue(args)); } lastcom = NOCOM; break; case '"': printf(args); break; } }