home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / libmocha / lm_jsd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  9.1 KB  |  343 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. /*
  20.  * JSDebug StreamConverter hooks for source text in Navigator
  21.  */
  22.  
  23. /* Please leave outside of ifdef for windows precompiled headers */
  24. #include "lm.h"
  25.  
  26. #include "jsdebug.h"
  27. #include "net.h"
  28. #include "prlink.h"
  29.  
  30.  
  31. #ifdef JSDEBUGGER
  32.  
  33. /***************************************/
  34. /* a static global, oh well... */
  35.  
  36. static JSDContext* g_jsdc = NULL;
  37.  
  38. typedef struct 
  39. {
  40.     NET_StreamClass* next_stream;
  41.     JSDSourceText*   jsdsrc;
  42.     
  43. } LocalData;
  44.  
  45. /***************************************/
  46. /* support for dynamic library load and calling */
  47.  
  48. /* these must match declarations in jsdebug.h */
  49.  
  50. typedef void 
  51. (*SetUserCallbacksProc)(JSRuntime* jsruntime, JSD_UserCallbacks* callbacks, void* user);
  52.  
  53. typedef JSDSourceText* 
  54. (*NewSourceTextProc)(JSDContext* jsdc, const char* url);
  55.  
  56. typedef JSDSourceText* 
  57. (*AppendSourceTextProc)(JSDContext* jsdc, 
  58.                      JSDSourceText* jsdsrc,
  59.                      const char* text,       /* *not* zero terminated */
  60.                      size_t length,
  61.                      JSDSourceStatus status);
  62.  
  63. static SetUserCallbacksProc g_SetUserCallbacks = NULL;
  64. static NewSourceTextProc    g_NewSourceText    = NULL;
  65. static AppendSourceTextProc g_AppendSourceText = NULL;
  66. static PRLibrary*           g_JSDModule        = NULL;
  67.  
  68. #ifdef XP_PC
  69. #if defined(_WIN32) || defined(XP_OS2)
  70.     static char moduleName[] = "jsd3240.dll";
  71. #else
  72.     static char moduleName[] = "jsd1640.dll";
  73. #endif /* _WIN32 */
  74. #endif /* XP_PC */
  75.  
  76. #ifdef XP_MAC
  77.     static char moduleName[] = "JavaScript Debug Support";
  78. #endif
  79.  
  80. #ifdef XP_UNIX
  81.     static char moduleName[] = "libjsd";
  82. #endif /*XP_UNIX */
  83.  
  84. #ifdef XP_UNIX
  85. static PRLibrary*
  86. LoadUnixLibrary(const char *name)
  87. {
  88.     PRLibrary* lib = NULL;
  89.     char* libPath;
  90.     char* fullname;
  91.     const char* rawLibPath;
  92.     char* cur;
  93.     char* next;
  94.  
  95.     rawLibPath = PR_GetLibraryPath();
  96.     if( ! rawLibPath )
  97.         return NULL;
  98.  
  99.     cur = libPath = strdup(rawLibPath);
  100.     if( ! libPath )
  101.         return NULL;
  102.  
  103.     do
  104.     {
  105.         next = strchr(cur, ':');
  106.         if(next)
  107.             *next++ = 0;
  108.  
  109.         if( cur[strlen(cur)-1] == '/' )
  110.             fullname = PR_smprintf("%s%s.%s", cur, name, DLL_SUFFIX);
  111.         else
  112.             fullname = PR_smprintf("%s/%s.%s", cur, name, DLL_SUFFIX);
  113.  
  114.         lib = PR_LoadLibrary(fullname);
  115.         free(fullname);
  116.  
  117.         if( lib )
  118.             break;
  119.     
  120.         cur = next;    
  121.     } while( cur && *cur );
  122.  
  123.     free(libPath);
  124.     return lib;
  125. #endif /*XP_UNIX */
  126.  
  127.  
  128. static void
  129. UnLoadJSDModule(void)
  130. {
  131.     if( g_JSDModule )
  132.         PR_UnloadLibrary(g_JSDModule);
  133.  
  134.     g_JSDModule         = NULL;
  135.     g_SetUserCallbacks  = NULL;
  136.     g_NewSourceText     = NULL;
  137.     g_AppendSourceText  = NULL;
  138. }
  139.  
  140. static int
  141. LoadJSDModuleAndCallbacks(void)
  142. {
  143. #ifdef XP_MAC
  144.     const char *libPath = PR_GetLibraryPath();
  145.     PR_SetLibraryPath( "/usr/local/netscape/" );
  146.     
  147.     g_JSDModule = PR_LoadLibrary(moduleName);
  148.     
  149.     /* set path back to original path (don't have ourselves in list) */
  150.     PR_SetLibraryPath( libPath );
  151. #elif defined(XP_UNIX)
  152.    g_JSDModule = LoadUnixLibrary(moduleName);
  153. #else
  154.    g_JSDModule = PR_LoadLibrary(moduleName);
  155. #endif
  156.     
  157.     if( ! g_JSDModule )
  158.         return 0;
  159.  
  160. #ifndef NSPR20
  161.     g_SetUserCallbacks = (SetUserCallbacksProc) PR_FindSymbol( "JSD_SetUserCallbacks" , g_JSDModule);
  162.     g_NewSourceText    = (NewSourceTextProc   ) PR_FindSymbol( "JSD_NewSourceText"    , g_JSDModule);
  163.     g_AppendSourceText = (AppendSourceTextProc) PR_FindSymbol( "JSD_AppendSourceText" , g_JSDModule);
  164. #else
  165.     g_SetUserCallbacks = (SetUserCallbacksProc) PR_FindSymbol( g_JSDModule, "JSD_SetUserCallbacks");
  166.     g_NewSourceText    = (NewSourceTextProc   ) PR_FindSymbol( g_JSDModule, "JSD_NewSourceText");
  167.     g_AppendSourceText = (AppendSourceTextProc) PR_FindSymbol( g_JSDModule, "JSD_AppendSourceText");
  168. #endif
  169.  
  170.     if( ! g_SetUserCallbacks    ||
  171.         ! g_NewSourceText       ||
  172.         ! g_AppendSourceText )
  173.     {
  174.         UnLoadJSDModule();
  175.         return 0;
  176.     }
  177.     return 1;
  178. }
  179.  
  180. /***************************************/
  181. /* helpers */
  182.  
  183. PR_STATIC_CALLBACK(void)
  184. lmjsd_SetContext(JSDContext* jsdc, void* user)
  185. {
  186.     g_jsdc = jsdc;
  187. }
  188.  
  189. static void cleanup_ld( LocalData* ld )
  190. {
  191.     if( ld )
  192.     {
  193.         XP_FREEIF(ld->next_stream);
  194.         XP_FREE(ld);
  195.     }
  196. }
  197.  
  198. /***************************************/
  199. /* converter callbacks */
  200.  
  201. PR_STATIC_CALLBACK(int)
  202. lmjsd_CvtPutBlock (NET_StreamClass *stream, const char *str, int32 len)
  203. {
  204.     LocalData* ld = (LocalData*) stream->data_object;
  205.  
  206.     if( g_jsdc && ld->jsdsrc )
  207.         ld->jsdsrc = g_AppendSourceText(g_jsdc, ld->jsdsrc,
  208.                                         str, len, JSD_SOURCE_PARTIAL );
  209.  
  210.     return ((*ld->next_stream->put_block)(ld->next_stream,str,len));
  211. }
  212.  
  213. PR_STATIC_CALLBACK(void)
  214. lmjsd_CvtComplete (NET_StreamClass *stream)
  215. {
  216.     LocalData* ld = (LocalData*) stream->data_object;
  217.     
  218.     if( g_jsdc && ld->jsdsrc )
  219.         g_AppendSourceText(g_jsdc, ld->jsdsrc,
  220.                            NULL, 0, JSD_SOURCE_COMPLETED );
  221.  
  222.     (*ld->next_stream->complete)(ld->next_stream);
  223.     
  224.     cleanup_ld(ld);    
  225. }
  226.  
  227. PR_STATIC_CALLBACK(void)
  228. lmjsd_CvtAbort (NET_StreamClass *stream, int status)
  229. {
  230.     LocalData* ld = (LocalData*) stream->data_object;
  231.     
  232.     if( g_jsdc && ld->jsdsrc )
  233.         g_AppendSourceText(g_jsdc, ld->jsdsrc,
  234.                            NULL, 0, JSD_SOURCE_ABORTED );
  235.     
  236.     (*ld->next_stream->abort)(ld->next_stream, status);
  237.     
  238.     cleanup_ld(ld);    
  239. }
  240.  
  241. PR_STATIC_CALLBACK(unsigned int)
  242. lmjsd_CvtWriteReady (NET_StreamClass *stream)
  243. {
  244.     LocalData* ld = (LocalData*) stream->data_object;
  245.     return (*ld->next_stream->is_write_ready)(ld->next_stream);
  246. }
  247.  
  248. /***************************************/
  249. /* exported functions */
  250.  
  251. void
  252. lm_InitJSDebug(JSRuntime *jsruntime)
  253. {
  254.     JSD_UserCallbacks cbs;
  255.  
  256.     if( LoadJSDModuleAndCallbacks() )
  257.     {
  258.         memset(&cbs, 0, sizeof(JSD_UserCallbacks) );
  259.         cbs.size        = sizeof(JSD_UserCallbacks);
  260.         cbs.setContext  = lmjsd_SetContext;
  261.         g_SetUserCallbacks( jsruntime, &cbs, &g_jsdc ); /* &g_jsdc is just a unique address */
  262.     }
  263.  
  264. }
  265.  
  266. void
  267. lm_ExitJSDebug(JSRuntime *jsruntime)
  268. {
  269.     if( g_SetUserCallbacks )
  270.         g_SetUserCallbacks( jsruntime, NULL, &g_jsdc ); /* &g_jsdc is just a unique address */
  271.     g_jsdc = NULL;
  272.     UnLoadJSDModule();
  273. }
  274.  
  275. JSBool
  276. LM_GetJSDebugActive(void)
  277. {
  278.     return (JSBool)(NULL != g_jsdc);
  279. }
  280.  
  281. void
  282. LM_JamSourceIntoJSDebug( const char *filename,
  283.                          const char *str, 
  284.                          int32      len,
  285.                          MWContext  *mwcontext )
  286. {
  287.     JSDSourceText* jsdsrc;
  288.  
  289.     if( ! g_jsdc )
  290.         return;
  291.  
  292.     jsdsrc = g_NewSourceText(g_jsdc, filename);
  293.     if( jsdsrc )
  294.         jsdsrc = g_AppendSourceText(g_jsdc, jsdsrc,
  295.                                     str, len, JSD_SOURCE_PARTIAL );
  296.     if( jsdsrc )
  297.         g_AppendSourceText(g_jsdc, jsdsrc,
  298.                            NULL, 0, JSD_SOURCE_COMPLETED );
  299. }
  300.  
  301. extern NET_StreamClass*
  302. LM_StreamBuilder( int         format_out,
  303.                   void        *data_obj,
  304.                   URL_Struct  *URL_s,
  305.                   MWContext   *mwcontext )
  306. {
  307.     LocalData*       ld;
  308.     NET_StreamClass* stream;
  309.  
  310.     /* If JSDebug is not active, then don't link into chain */
  311.     if( ! g_jsdc )
  312.         return NET_StreamBuilder(format_out, URL_s, mwcontext);
  313.  
  314.     if( ! (ld = XP_NEW_ZAP(LocalData)) ||
  315.         ! (ld->jsdsrc = g_NewSourceText(g_jsdc, URL_s->address)) )
  316.     {
  317.         cleanup_ld(ld);
  318.         return NET_StreamBuilder(format_out, URL_s, mwcontext);
  319.     }
  320.  
  321.     if( ! (stream = NET_NewStream("JSDebuggerConverter", lmjsd_CvtPutBlock,
  322.                                   lmjsd_CvtComplete, lmjsd_CvtAbort, 
  323.                                   lmjsd_CvtWriteReady, ld, mwcontext)) )
  324.     {
  325.         g_AppendSourceText(g_jsdc, ld->jsdsrc, NULL, 0, JSD_SOURCE_FAILED);
  326.         cleanup_ld(ld);
  327.         return NET_StreamBuilder(format_out, URL_s, mwcontext);
  328.     }
  329.  
  330.     if( ! (ld->next_stream = NET_StreamBuilder(format_out, URL_s, mwcontext)) )
  331.     {
  332.         g_AppendSourceText(g_jsdc, ld->jsdsrc, NULL, 0, JSD_SOURCE_FAILED);
  333.         cleanup_ld(ld);
  334.         XP_FREE(stream);
  335.         return NULL;
  336.     }
  337.  
  338.     return stream;
  339. }
  340.  
  341. #endif /* JSDEBUGGER */
  342.