home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / modules / libhook / src / hk_init.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  8.0 KB  |  413 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. #include "xp_core.h"
  19. #include "xp_mcom.h"
  20. #include "hk_types.h"
  21. #include "jsapi.h"
  22. #include "prefapi.h"
  23. #include "ntypes.h"
  24. #include "structs.h"
  25. #include "pa_tags.h"
  26.  
  27. #include "hk_private.h"
  28.  
  29. #ifdef XP_MAC
  30. #include "hk_funcs.h"
  31. #endif
  32.  
  33.  
  34. static hk_FunctionRec **FunctionList = NULL;
  35. static int32 FunctionCount = 0;
  36.  
  37. static char *hk_FunctionStrings[HK_MAX] = {
  38.     NULL,
  39.     "location_hook",
  40.     "_hook",
  41.     "document_start_hook"};
  42.  
  43. static JSClass autoconf_class = {
  44.     "HookConfig", 0,
  45.     hk_HookObjectAddProperty, hk_HookObjectDeleteProperty,
  46.     JS_PropertyStub, hk_HookObjectSetProperty,
  47.     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
  48. };
  49.  
  50.  
  51. /*******************************************
  52.  * This function really bugs me!  It needs to
  53.  * be super fast since it will be called for every
  54.  * HTML tag ever processed.  This means it should be
  55.  * self-contained, and not call off to other functions.
  56.  * Making it do that means it can't call off into
  57.  * hk_tag.c to get inside the PA_Tag structure in extra,
  58.  * and thus makes me include ntypes.h, structs.h, and pa_tags.h.
  59.  ********************************************/
  60. /*
  61.  * A FAST function existence lookup, using an array set up in
  62.  * the initialization process.
  63.  */
  64. intn
  65. HK_IsHook(int32 hook_id, void *extra)
  66. {
  67.     int32 func_id;
  68.     hk_FunctionRec *rec_ptr;
  69.  
  70.     /*
  71.      * The no hook case never exists.
  72.      */
  73.     if (hook_id == HK_NONE)
  74.     {
  75.         return 0;
  76.     }
  77.     /*
  78.      * Tag hooks map to the tag types, or alternatly
  79.      * unknown tags which are handled elsewhere.
  80.      */
  81.     else if (hook_id == HK_TAG)
  82.     {
  83.         PA_Tag *tag;
  84.  
  85.         tag = (PA_Tag *)extra;
  86.         if (tag->type != P_UNKNOWN)
  87.         {
  88.             func_id = HK_MAX - 1 + tag->type;
  89.         }
  90.         /*
  91.          * P_UNKNOWN tags must be looked up the slow
  92.          * dynamic way.
  93.          */
  94.         else
  95.         {
  96.             return(hk_IsUnknownTagHook(extra));
  97.         }
  98.     }
  99.     else
  100.     {
  101.         func_id = hook_id - 1;
  102.     }
  103.  
  104.     /*
  105.      * If we are outside the known funtion array, fail.
  106.      */
  107.     if ((func_id < 0)||(func_id >= FunctionCount))
  108.     {
  109.         return 0;
  110.     }
  111.  
  112.     /*
  113.      * If no function is registered, fail.
  114.      */
  115.     rec_ptr = FunctionList[func_id];
  116.     if (rec_ptr == NULL)
  117.     {
  118.         return 0;
  119.     }
  120.  
  121.     if (rec_ptr->func_exists == FALSE)
  122.     {
  123.         return 0;
  124.     }
  125.     else
  126.     {
  127.         return 1;
  128.     }
  129. }
  130.  
  131.  
  132. /*
  133.  * Set the existence state of a particular index in the array.
  134.  */
  135. static void
  136. hk_set_function_existence(int32 indx, XP_Bool exists)
  137. {
  138.     if ((indx < 0)||(indx >= FunctionCount))
  139.     {
  140.         return;
  141.     }
  142.  
  143.     if (FunctionList[indx] != NULL)
  144.     {
  145.         FunctionList[indx]->func_exists = exists;
  146.     }
  147. }
  148.  
  149.  
  150. void
  151. hk_SetFunctionExistence(char *func_name, XP_Bool exists)
  152. {
  153.     int32 i, len;
  154.     char *tptr;
  155.     char *up_str;
  156.     char *ptr1, *ptr2;
  157.     int32 indx;
  158.  
  159.     /*
  160.      * A NULL function one too short for the hook suffix
  161.      * cannot be a hook function.
  162.      */
  163.     if (func_name == NULL)
  164.     {
  165.         return;
  166.     }
  167.     len = XP_STRLEN(func_name);
  168.     if (len < XP_STRLEN("_hook"))
  169.     {
  170.         return;
  171.     }
  172.  
  173.     /*
  174.      * If the function has no hook suffix we just don't care.
  175.      */
  176.     tptr = func_name + len - XP_STRLEN("_hook");
  177.     if (XP_STRCMP(tptr, "_hook") != 0)
  178.     {
  179.         return;
  180.     }
  181.  
  182.  
  183.     /*
  184.      * Make an all upper-case copy of the prefix.
  185.      */
  186.     *tptr = '\0';
  187.     up_str = XP_ALLOC(XP_STRLEN(func_name) + 1);
  188.     /*
  189.      * If allocation fails, restore original and return.
  190.      */
  191.     if (up_str == NULL)
  192.     {
  193.         *tptr = '_';
  194.         return;
  195.     }
  196.     ptr1 = func_name;
  197.     ptr2 = up_str;
  198.     while (*ptr1 != '\0')
  199.     {
  200.         *ptr2 = (char)(XP_TO_UPPER(*ptr1));
  201.         ptr1++;
  202.         ptr2++;
  203.     }
  204.     *ptr2 = '\0';
  205.     *tptr = '_';
  206.  
  207.     /*
  208.      * Check if the prefix is a known TAG name.
  209.      */
  210.     indx = hk_TagStringToIndex(up_str);
  211.     XP_FREE(up_str);
  212.     if (indx >= 0)
  213.     {
  214.         indx = HK_MAX - 1 + indx;
  215.         hk_set_function_existence(indx, exists);
  216.         return;
  217.     }
  218.  
  219.     /*
  220.      * Special check for the TEXT_hook which is a tag hook but
  221.      * won't be caught by the hk_TagStringToIndex test.
  222.      */
  223.     if (XP_STRCMP(func_name, "TEXT_hook") == 0)
  224.     {
  225.         indx = HK_MAX - 1 + 0;
  226.         hk_set_function_existence(indx, exists);
  227.         return;
  228.     }
  229.  
  230.     /*
  231.      * Finally, check the array of known tag hooks.
  232.      */
  233.     for (i=1; i<HK_MAX; i++)
  234.     {
  235.         if ((hk_FunctionStrings[i] != NULL)&&
  236.             (XP_STRCMP(func_name, hk_FunctionStrings[i]) == 0))
  237.         {
  238.             indx = i - 1;
  239.             hk_set_function_existence(indx, exists);
  240.             return;
  241.         }
  242.     }
  243. }
  244.  
  245.  
  246. /*
  247.  * Free all members of the function list array up to
  248.  * the passed index.
  249.  */
  250. static void
  251. hk_free_function_list(int32 indx)
  252. {
  253.     int32 i;
  254.  
  255.     for (i=0; i<indx; i++)
  256.     {
  257.         if (FunctionList[i] != NULL)
  258.         {
  259.             if (FunctionList[i]->func_name != NULL)
  260.             {
  261.                 XP_FREE(FunctionList[i]->func_name);
  262.                 FunctionList[i]->func_name = NULL;
  263.             }
  264.             XP_FREE(FunctionList[i]);
  265.             FunctionList[i] = NULL;
  266.         }
  267.     }
  268.     XP_FREE(FunctionList);
  269.     FunctionList = NULL;
  270.     FunctionCount = 0;
  271. }
  272.  
  273.  
  274. /*
  275.  * Initialize the function list array to contain all the known tags
  276.  * plus all the known special hook functions.
  277.  */
  278. static intn
  279. hk_initialize_function_list(void)
  280. {
  281.     int32 i, indx;
  282.     int32 tag_cnt;
  283.  
  284.     /*
  285.      * Subtract one from HK_MAX because it includes the unknown
  286.      * at 0.  For the tag count, unknown is -1, so we can just
  287.      * use it as is.
  288.      */
  289.     tag_cnt = hk_NumKnownTags();
  290.     FunctionCount = HK_MAX - 1 + tag_cnt;
  291.     FunctionList = (hk_FunctionRec **)XP_ALLOC(FunctionCount *
  292.                         sizeof(hk_FunctionRec *));
  293.     if (FunctionList == NULL)
  294.     {
  295.         return 0;
  296.     }
  297.  
  298.     indx = 0;
  299.     /*
  300.      * First allocate all the known special hooks.
  301.      */
  302.     for (i=1; i < HK_MAX; i++)
  303.     {
  304.         hk_FunctionRec *rec_ptr;
  305.  
  306.         rec_ptr = XP_NEW(hk_FunctionRec);
  307.         if (rec_ptr == NULL)
  308.         {
  309.             hk_free_function_list(indx);
  310.             return 0;
  311.         }
  312.         rec_ptr->func_exists = FALSE;
  313.         rec_ptr->func_name = hk_FunctionStrings[i];
  314.         FunctionList[indx] = rec_ptr;
  315.         indx++;
  316.     }
  317.  
  318.     /*
  319.      * Now do all known tags.
  320.      */
  321.     for (i=0; i < tag_cnt; i++)
  322.     {
  323.         hk_FunctionRec *rec_ptr;
  324.  
  325.         rec_ptr = XP_NEW(hk_FunctionRec);
  326.         if (rec_ptr == NULL)
  327.         {
  328.             hk_free_function_list(indx);
  329.             return 0;
  330.         }
  331.         rec_ptr->func_exists = FALSE;
  332.         rec_ptr->func_name = hk_TagIndexToFunctionString(i);
  333.         FunctionList[indx] = rec_ptr;
  334.         indx++;
  335.     }
  336.  
  337.     return 1;
  338. }
  339.  
  340.  
  341. /*
  342.  * Initialize all the libhook stuff.  SHould only be called once.
  343.  * Usually just before reading hook.js.
  344.  */
  345. intn
  346. HK_Init(void)
  347. {
  348.     intn ret;
  349.     JSContext *j_context;
  350.     JSObject *j_object;
  351.     JSObject *hook_obj;
  352.  
  353.     /*
  354.      * If a hook object does not already exist, create
  355.      * one.  If you cannot create one, then return failure.
  356.      */
  357.     hook_obj = hk_GetHookObject();
  358.     if (hook_obj == NULL)
  359.     {
  360.         if ((!PREF_GetConfigContext(&j_context))||
  361.             (!PREF_GetGlobalConfigObject(&j_object)))
  362.         {
  363.             return 0;
  364.         }
  365.  
  366.         hook_obj = JS_DefineObject(j_context, j_object,
  367.             "HookConfig",
  368.             &autoconf_class,
  369.             NULL,
  370.             JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT);
  371.     }
  372.     if (hook_obj == NULL)
  373.     {
  374.         return 0;
  375.     }
  376.  
  377.     hk_SetHookObject(hook_obj);
  378.  
  379.     ret = hk_initialize_function_list();
  380.  
  381.     return ret;
  382. }
  383.  
  384.  
  385. /*
  386.  * Get the hook know for the passed hook id.
  387.  */
  388. const char *
  389. HK_GetFunctionName(int32 hook_id, void *extra)
  390. {
  391.     if ((hook_id < 0)||(hook_id >= HK_MAX))
  392.     {
  393.         return NULL;
  394.     }
  395.  
  396.     /*
  397.      * Special name creation for tag hooks.
  398.      */
  399.     if (hook_id == HK_TAG)
  400.     {
  401.         const char *ret_str;
  402.  
  403.         ret_str = (const char *)hk_TagFunctionString(
  404.                 hk_FunctionStrings[hook_id], extra);
  405.         return ret_str;
  406.     }
  407.     else
  408.     {
  409.         return hk_FunctionStrings[hook_id];
  410.     }
  411. }
  412.  
  413.