ddemain_xsb.c

00001 /* File:      ddemain_xsb.c (for windows)
00002 ** Author(s): Warren
00003 ** Contact:   xsb-contact@cs.sunysb.edu
00004 ** 
00005 ** Copyright (C) The Research Foundation of SUNY, 1998
00006 ** 
00007 ** XSB is free software; you can redistribute it and/or modify it under the
00008 ** terms of the GNU Library General Public License as published by the Free
00009 ** Software Foundation; either version 2 of the License, or (at your option)
00010 ** any later version.
00011 ** 
00012 ** XSB is distributed in the hope that it will be useful, but WITHOUT ANY
00013 ** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014 ** FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License for
00015 ** more details.
00016 ** 
00017 ** You should have received a copy of the GNU Library General Public License
00018 ** along with XSB; if not, write to the Free Software Foundation,
00019 ** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00020 **
00021 ** $Id: ddemain_xsb.c,v 1.1 1999/10/25 06:00:22 kifer Exp $
00022 ** 
00023 */
00024 
00025 
00026 #define INCLUDE_DDEML_H
00027 #include <windows.h>
00029 #include <stdio.h>
00030 #include <string.h>
00031 #include <malloc.h>
00032 #include "cinterf.h"
00033 
00034 #define WM_USER_INITIATE (WM_USER+1)
00035 DWORD idInst;
00036 HWND hwnd;
00037 char szAppName[] = "XSBWin";
00038 char szTopic[] = "square";
00039 HSZ hszService;
00040 
00041 char tempstring[100];
00042 long int rcode;
00043 char szBuffer[256];
00044 char szBuff1[256];
00045 char szBuff2[256];
00046 char *szQuery;
00047 char *szBuff3;
00048 #define initsizeBuff3 500
00049 long int sizeBuff3 = 0;
00050   
00051 long FAR PASCAL _export xsbProc(HWND,UINT,UINT,LONG);
00052 HDDEDATA FAR PASCAL _export DdeCallback(
00053         UINT,UINT,HCONV,HSZ,HSZ,HDDEDATA,DWORD,DWORD);
00054 
00055 /* quick test to see whether atom must be quoted */
00056 int mustquote(char *atom)
00057 {
00058     int i;
00059 
00060     if (!(atom[0] >= 'a' && atom[0] <= 'z')) return TRUE;
00061     for (i=1; atom[i] != '\0'; i++) {
00062         if (!((atom[i] >= 'a' && atom[i] <= 'z') ||
00063              (atom[i] >= 'A' && atom[i] <= 'Z') ||
00064              (atom[i] == '_') ||
00065              (atom[i] >= '0' && atom[i] <= '9')
00066              )) return TRUE;
00067     }
00068     return FALSE;
00069 }
00070 
00071 /* copy a string (quoted if !toplevel and necessary) into a buffer.  */
00072 void printpstring(char *atom, int toplevel, char *straddr, long int *ind)
00073 {
00074     int i;
00075    
00076     if (toplevel || !mustquote(atom)) {
00077         strcpy(straddr+*ind,atom);
00078         *ind += strlen(atom);
00079     } else {
00080         straddr[(*ind)++] = '\'';
00081         for (i = 0; atom[i] != '\0'; i++) {
00082             straddr[(*ind)++] = atom[i];
00083             if (atom[i] == '\'') straddr[(*ind)++] = '\'';
00084         }
00085         straddr[(*ind)++] = '\'';
00086     }
00087 }
00088     
00089 /* calculate approximate length of a printed term.  For space alloc. */
00090 DWORD clenpterm(prolog_term term)
00091 {
00092   int i, clen;
00093 
00094   if (is_var(term)) return 11;
00095   else if (is_int(term)) return 12;
00096   else if (is_float(term)) return 12;
00097   else if (is_nil(term)) return 2;
00098   else if (is_string(term)) return strlen(p2c_string(term))+5;
00099   else if (is_list(term)) {
00100       clen = 1;
00101       clen += clenpterm(p2p_car(term)) + 1;
00102       while (is_list(term)) {
00103           clen += clenpterm(p2p_car(term)) + 1;
00104           term = p2p_cdr(term);
00105       }
00106       if (!is_nil(term)) {
00107           clen += clenpterm(term) + 1;
00108       }
00109       return clen+1;
00110   } else if (is_functor(term)) {
00111       clen = strlen(p2c_functor(term))+5;
00112       if (p2c_arity(term) > 0) {
00113           clen += clenpterm(p2p_arg(term,1)) + 1;
00114           for (i = 2; i <= p2c_arity(term); i++) {
00115               clen += clenpterm(p2p_arg(term,i)) + 1;
00116           }
00117           return clen + 1;
00118       } else return clen;
00119   } else {
00120       fprintf(stderr,"error, unrecognized type");
00121       return 0;
00122   }
00123 }
00124 
00125 /* print a prolog_term into a buffer.
00126 (Atoms are quoted if !toplevel and it's necessary for Prolog reading) */
00127 void printpterm(prolog_term term, int toplevel, char *straddr, long int *ind)
00128 {
00129   int i;
00130 
00131   if (is_var(term)) {
00132       sprintf(tempstring,"_%p",term);
00133       strcpy(straddr+*ind,tempstring);
00134       *ind += strlen(tempstring);
00135   } else if (is_int(term)) {
00136       sprintf(tempstring,"%d",p2c_int(term));
00137       strcpy(straddr+*ind,tempstring);
00138       *ind += strlen(tempstring);
00139   } else if (is_float(term)) {
00140       sprintf(tempstring,"%f",p2c_float(term));
00141       strcpy(straddr+*ind,tempstring);
00142       *ind += strlen(tempstring);
00143   } else if (is_nil(term)) {
00144       strcpy(straddr+*ind,"[]");
00145       *ind += 2;
00146   } else if (is_string(term)) {
00147       printpstring(p2c_string(term),toplevel,straddr,ind);
00148   } else if (is_list(term)) {
00149       strcpy(straddr+*ind,"[");
00150       *ind += 1;
00151       printpterm(p2p_car(term),FALSE,straddr,ind);
00152       term = p2p_cdr(term);
00153       while (is_list(term)) {
00154           strcpy(straddr+*ind,",");
00155           *ind += 1;
00156           printpterm(p2p_car(term),FALSE,straddr,ind);
00157           term = p2p_cdr(term);
00158       }
00159       if (!is_nil(term)) {
00160           strcpy(straddr+*ind,"|");
00161           *ind += 1;
00162           printpterm(term,FALSE,straddr,ind);
00163       }
00164       strcpy(straddr+*ind,"]");
00165       *ind += 1;
00166   } else if (is_functor(term)) {
00167       printpstring(p2c_functor(term),FALSE,straddr,ind);
00168       if (p2c_arity(term) > 0) {
00169           strcpy(straddr+*ind,"(");
00170           *ind += 1;
00171           printpterm(p2p_arg(term,1),FALSE,straddr,ind);
00172           for (i = 2; i <= p2c_arity(term); i++) {
00173               strcpy(straddr+*ind,",");
00174               *ind += 1;
00175               printpterm(p2p_arg(term,i),FALSE,straddr,ind);
00176           }
00177           strcpy(straddr+*ind,")");
00178           *ind += 1;
00179       }
00180   } else fprintf(stderr,"error, unrecognized type");
00181 }
00182 
00183 /* Windows main routine */
00184 int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
00185                     LPSTR lpszCmdParam, int nCmdShow)
00186 {
00187     MSG msg;
00188     WNDCLASS wndclass;
00189     FARPROC pfnDdeCallback;
00190     UINT ddeerror;
00191     int argc = 3;
00192     char *argv[] = {"xsb","-i","-n"};
00193 
00194     if (hPrevInstance) return FALSE;
00195 
00196     wndclass.style = 0;
00197     wndclass.lpfnWndProc = xsbProc;
00198     wndclass.cbClsExtra = 0;
00199     wndclass.cbWndExtra = 0;
00200     wndclass.hInstance = hInstance;
00201     wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
00202     wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
00203     wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
00204     wndclass.lpszMenuName = NULL;
00205     wndclass.lpszClassName = szAppName;
00206 
00207     RegisterClass(&wndclass);
00208 
00209     hwnd = CreateWindow(szAppName,"XSB DDE Server",WS_OVERLAPPEDWINDOW,
00210                         CW_USEDEFAULT,CW_USEDEFAULT,    // x,y position
00211                         CW_USEDEFAULT,CW_USEDEFAULT,    // 200,100,    // x,y size
00212                         NULL,NULL,hInstance,NULL);
00213 
00214     ShowWindow(hwnd,nCmdShow);  // nCmdShow
00215     UpdateWindow(hwnd);
00216 
00217     /* Initialize for DDE */
00218     pfnDdeCallback = MakeProcInstance((FARPROC)DdeCallback,hInstance);
00219     idInst = 0;
00220     ddeerror = DdeInitialize(&idInst,
00221                         (PFNCALLBACK)pfnDdeCallback,
00222                         CBF_SKIP_REGISTRATIONS | CBF_SKIP_UNREGISTRATIONS,
00223                         0L);
00224     if (ddeerror) {
00225         sprintf(tempstring,"Could not initialize server!\n  rc=%x, idInst=%x",ddeerror,idInst);
00226         MessageBox(hwnd,tempstring,szAppName, MB_ICONEXCLAMATION|MB_OK);
00227         DestroyWindow(hwnd);
00228         return FALSE;
00229     }
00230     
00231     freopen("xsblog","w",stdout);
00232     freopen("xsblog","a",stderr);
00233     
00234     /* Initialize xsb */
00235     xsb_init(argc,argv);
00236 
00237         /* This seems necessary??? huh???     
00238     rcode = xsb_query_string("true.");
00239     while (!rcode) {rcode = xsb_next();} */
00240 
00241     hszService = DdeCreateStringHandle(idInst,szAppName,0);
00242     DdeNameService(idInst,hszService,NULL,DNS_REGISTER);
00243     
00244     /* sprintf(tempstring,"XSB INITIALIZED!\n  rc=%x, idInst=%x",ddeerror,idInst);
00245     MessageBox(hwnd,tempstring,szAppName, MB_ICONEXCLAMATION|MB_OK); */
00246 
00247     while (GetMessage(&msg,NULL,0,0)) {
00248       TranslateMessage(&msg);
00249       DispatchMessage(&msg);
00250     }
00251     
00252     /* Close XSB connection */
00253     xsb_close();
00254 
00255     /* terminate DDE */
00256     (void) DdeFreeStringHandle(idInst,hszService);
00257     FreeProcInstance(pfnDdeCallback);
00258     DdeUninitialize(idInst);
00259 
00260     return msg.wParam;
00261 }
00262 
00263 long FAR PASCAL _export xsbProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
00264 {
00265     HDC hdc;
00266     PAINTSTRUCT ps;
00267     RECT rect;
00268 
00269     switch (message) {
00270       case WM_PAINT:
00271         
00272         hdc = BeginPaint(hwnd,&ps);
00273         GetClientRect(hwnd,&rect);
00274         DrawText(hdc,"XSB running",-1,&rect,
00275                 DT_SINGLELINE | DT_CENTER | DT_VCENTER);
00276         EndPaint(hwnd,&ps);
00277         return 0;
00278 
00279       case WM_DESTROY:
00280         PostQuitMessage(0);
00281         return 0;
00282     }
00283     return DefWindowProc(hwnd,message,wParam,lParam);
00284 }
00285 
00286 HDDEDATA FAR PASCAL _export DdeCallback(UINT type, UINT fmt,
00287                         HCONV hConv, HSZ hsz1, HSZ hsz2,
00288                         HDDEDATA data, DWORD data1,
00289                         DWORD data2)
00290 {
00291   long int ind, i, spaceneeded, sizeQuery;
00292   DWORD Qlen, QSegLen;
00293   static HCONV handConv;
00294   static HDDEDATA hdDataHandle;
00295 
00296     /*DdeQueryString(idInst,hsz1,szBuff1,sizeof(szBuff1),0);
00297     DdeQueryString(idInst,hsz2,szBuff2,sizeof(szBuff2),0);
00298     
00299     fprintf(stderr,"DDE Callback, type=%d, fmt=%d, hConv=%d, hsz1=%s, hsz2=%s,\n d1=%x, d2=%x\n",
00300         type,fmt,hConv,szBuff1,szBuff2,data1,data2);*/
00301 
00302     
00303     switch (type) {
00304       case XTYP_ERROR:
00305         fprintf(stderr,"error: xtyp_error\n");
00306         return NULL;
00307       case XTYP_ADVDATA:
00308         fprintf(stderr,"DDE msg received ADVDATA\n");
00309         return DDE_FNOTPROCESSED;
00310       case XTYP_ADVREQ:
00311         fprintf(stderr,"DDE msg received ADVREQ\n");
00312         return NULL;
00313       case XTYP_ADVSTART:
00314         fprintf(stderr,"DDE msg received ADVSTART\n");
00315         return NULL;
00316       case XTYP_ADVSTOP:
00317         fprintf(stderr,"DDE msg received ADVSTOP\n");
00318         return NULL;
00319       
00320       case XTYP_CONNECT:
00321         DdeQueryString(idInst,hsz2,szBuffer,sizeof(szBuffer),0);
00322         if (strcmp(szBuffer,szAppName)) return FALSE;
00323         Qlen = DdeQueryString(idInst,hsz1,NULL,0,0);
00324         szQuery = (char *)malloc(Qlen+1);
00325         (void)DdeQueryString(idInst,hsz1,szQuery,Qlen+1,0);
00326         if (!strcmp(szQuery,"XSB")) {
00327             free(szQuery);
00328             szQuery = NULL;
00329         }
00330         return TRUE;
00331 
00332       case XTYP_CONNECT_CONFIRM:
00333         handConv = hConv;
00334         return TRUE;
00335 
00336       case XTYP_DISCONNECT:
00337         return NULL;
00338       case XTYP_EXECUTE:
00339         fprintf(stderr,"DDE msg received EXECUTE\n");
00340         return DDE_FNOTPROCESSED;
00341 
00342       case XTYP_POKE:
00343         QSegLen = DdeGetData(data,NULL,100000,0L);
00344         if (!szQuery) {
00345             szQuery = (char *)malloc(QSegLen);
00346             QSegLen = DdeGetData(data,szQuery,100000,0L);
00347             sizeQuery = QSegLen;
00348         } else {
00349             szQuery = (char *)realloc(szQuery,sizeQuery+QSegLen+1);
00350             QSegLen = DdeGetData(data,szQuery+sizeQuery,100000,0L);
00351             sizeQuery =+ QSegLen;
00352         }
00353         return DDE_FACK;
00354         
00355       case XTYP_REGISTER:
00356         fprintf(stderr,"DDE msg received REGISTER\n");
00357         return NULL;
00358 
00359       case XTYP_REQUEST:
00360         /*fprintf(stderr,"DDE msg received REQUEST:\n");*/
00361         if (!szQuery) return NULL;
00362         if (sizeBuff3 < 10) {
00363             szBuff3 = (char *)malloc(initsizeBuff3);
00364             sizeBuff3 = initsizeBuff3;
00365         }
00366         ind = 0;
00367         rcode = xsb_query_string(szQuery);      /* call the query */
00368         if (rcode) {
00369             strcpy(szBuff3+ind,"no\r");
00370             ind += 3;
00371         } else if (is_string(reg_term(2)) || p2c_arity(reg_term(2))==0) {
00372             strcpy(szBuff3+ind,"yes\r");
00373             ind += 4;
00374             while (!rcode) rcode = xsb_next();
00375         } else while (!rcode) {
00376             spaceneeded = ind + clenpterm(reg_term(2)) + 20;  /* fudge factor */
00377             if (spaceneeded > sizeBuff3) {
00378                 while (spaceneeded > sizeBuff3) {sizeBuff3 = 2*sizeBuff3;}
00379                 szBuff3 = realloc(szBuff3,sizeBuff3);
00380             }
00381             for (i=1; i<p2c_arity(reg_term(2)); i++) {
00382                 printpterm(p2p_arg(reg_term(2),i),TRUE,szBuff3,&ind);
00383                 strcpy(szBuff3+ind,"\t");
00384                 ind += 1;
00385             }
00386             printpterm(p2p_arg(reg_term(2),p2c_arity(reg_term(2))),TRUE,szBuff3,&ind);
00387             strcpy(szBuff3+ind,"\r");
00388             ind += 1;
00389             rcode = xsb_next();
00390         }
00391         hdDataHandle = DdeCreateDataHandle(idInst,szBuff3,ind+1,0,hsz2,CF_TEXT,0);
00392         free(szQuery);
00393         szQuery = NULL;
00394         return hdDataHandle;
00395 
00396       case XTYP_WILDCONNECT:
00397         fprintf(stderr,"DDE msg received WILDCONNECT\n");
00398         return NULL;
00399       default:
00400         fprintf(stderr,"DDE msg received: %d\n",type);        
00401     }
00402     return NULL;
00403 }
00404 

Generated on Wed Jul 26 13:30:40 2006 for XSB by  doxygen 1.4.5