home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / tcl / tclX6.5c / src / tclXmsgcat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-19  |  9.4 KB  |  357 lines

  1. /* 
  2.  * tclXmsgcat.c --
  3.  *
  4.  *      Contains commands for accessing XPG/3 message catalogs.  If real XPG/3
  5.  * message catalogs are not available, the default string is returned.
  6.  *-----------------------------------------------------------------------------
  7.  * Copyright 1992 Karl Lehenbauer and Mark Diekhans.
  8.  *
  9.  * Permission to use, copy, modify, and distribute this software and its
  10.  * documentation for any purpose and without fee is hereby granted, provided
  11.  * that the above copyright notice appear in all copies.  Karl Lehenbauer and
  12.  * Mark Diekhans make no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without express or
  14.  * implied warranty.
  15.  *-----------------------------------------------------------------------------
  16.  * $Id: tclXmsgcat.c,v 2.0 1992/10/16 04:51:02 markd Rel $
  17.  *-----------------------------------------------------------------------------
  18.  */
  19.  
  20. #include "tclExtdInt.h"
  21.  
  22. #ifdef TCL_HAVE_CATGETS
  23.  
  24. #include <nl_types.h>
  25.  
  26. #else
  27.  
  28. typedef int nl_catd;
  29.  
  30. #endif /* TCL_HAVE_CATGETS */
  31.  
  32. int
  33. ParseFailOption _ANSI_ARGS_((Tcl_Interp *interp,
  34.                              CONST char *optionStr,
  35.                              int        *failPtr));
  36.  
  37. int
  38. CatOpFailed _ANSI_ARGS_((Tcl_Interp *interp,
  39.                          CONST char *errorMsg));
  40.  
  41. /*
  42.  * Message catalog table is global, so it is shared between all interpreters
  43.  * in the same process.
  44.  */
  45. static void_pt msgCatTblPtr = NULL;
  46.  
  47. #ifndef TCL_HAVE_CATGETS
  48.  
  49. /*
  50.  *-----------------------------------------------------------------------------
  51.  *
  52.  * catopen --
  53.  *    A stub to use when message catalogs are not available.
  54.  *
  55.  * Results:
  56.  *     Always returns the default string.
  57.  *
  58.  *-----------------------------------------------------------------------------
  59.  */
  60. static nl_catd
  61. catopen (name, oflag)
  62.     char *name;
  63.     int   oflag;
  64. {
  65.     return (nl_catd) -1;
  66. }
  67.  
  68. /*
  69.  *-----------------------------------------------------------------------------
  70.  *
  71.  * catgets --
  72.  *    A stub to use when message catalogs are not available.
  73.  *
  74.  * Results:
  75.  *     Always returns -1.
  76.  *
  77.  *-----------------------------------------------------------------------------
  78.  */
  79. static char *
  80. catgets (catd, set_num, msg_num, defaultStr)
  81.     nl_catd catd;
  82.     int     set_num, msg_num;
  83.     char   *defaultStr;
  84. {
  85.     return defaultStr;
  86. }
  87.  
  88. /*
  89.  *-----------------------------------------------------------------------------
  90.  *
  91.  * catclose --
  92.  *    A stub to use when message catalogs are not available.
  93.  *
  94.  * Results:
  95.  *     Always returns -1.
  96.  *
  97.  *-----------------------------------------------------------------------------
  98.  */
  99. static int
  100. catclose (catd)
  101.     nl_catd catd;
  102. {
  103.     return -1;
  104. }
  105. #endif /* TCL_HAVE_CATGETS */
  106.  
  107. /*
  108.  *-----------------------------------------------------------------------------
  109.  *
  110.  * ParseFailOption --
  111.  *    Parse the -fail/-nofail option, if specified.
  112.  *
  113.  * Results:
  114.  *     Standard Tcl results.
  115.  *
  116.  *-----------------------------------------------------------------------------
  117.  */
  118. static int
  119. ParseFailOption (interp, optionStr, failPtr)
  120.     Tcl_Interp *interp;
  121.     CONST char *optionStr;
  122.     int        *failPtr;
  123. {
  124.     if (STREQU ("-fail", ((char *) optionStr)))
  125.         *failPtr = TRUE;
  126.     else if (STREQU ("-nofail", ((char *) optionStr)))
  127.         *failPtr = FALSE;
  128.     else {
  129.         Tcl_AppendResult (interp, "Expected option of `-fail' or ",
  130.                           "`-nofail', got: `", optionStr, "'",
  131.                           (char *) NULL);
  132.         return TCL_ERROR;
  133.     }
  134.     return TCL_OK;
  135. }
  136.  
  137. /*
  138.  *-----------------------------------------------------------------------------
  139.  *
  140.  * CatOpFailed --
  141.  *    Handles failures of catopen and catclose.  If message catalogs are
  142.  * available, if returns the supplied message.  If message are not
  143.  * available, it returns a message indicating that message stubs are used.
  144.  * It is not specified by XPG/3 how to get the details of a message catalog
  145.  * open or close failure.
  146.  *
  147.  * Results:
  148.  *     Always returns TCL_ERROR;
  149.  *
  150.  *-----------------------------------------------------------------------------
  151.  */
  152. static int
  153. CatOpFailed (interp, errorMsg)
  154.     Tcl_Interp *interp;
  155.     CONST char *errorMsg;
  156. {
  157. #ifdef TCL_HAVE_CATGETS
  158.  
  159.     Tcl_AppendResult (interp, errorMsg, (char *) NULL);
  160.  
  161. #else
  162.  
  163.     Tcl_AppendResult (interp, "the message catalog facility is not available,",
  164.                       " default string is always returned", (char *) NULL);
  165.  
  166. #endif /* TCL_HAVE_CATGETS */
  167.  
  168.     return TCL_ERROR;
  169. }
  170.  
  171. /*
  172.  *-----------------------------------------------------------------------------
  173.  *
  174.  * Tcl_CatopenCmd --
  175.  *    Implements the TCL echo command:
  176.  *        catopen [-fail|-nofail] catname
  177.  *
  178.  * Results:
  179.  *     Standard Tcl results.
  180.  *
  181.  *-----------------------------------------------------------------------------
  182.  */
  183. static int
  184. Tcl_CatopenCmd (clientData, interp, argc, argv)
  185.     ClientData  clientData;
  186.     Tcl_Interp *interp;
  187.     int         argc;
  188.     char      **argv;
  189. {
  190.     int      fail;
  191.     nl_catd  catDesc;
  192.     nl_catd *catDescPtr;
  193.  
  194.     if ((argc < 2) || (argc > 3)) {
  195.         Tcl_AppendResult (interp, argv [0], " [-fail|-nofail] catname",
  196.                           (char *) NULL);
  197.         return TCL_ERROR;
  198.     }
  199.     if (argc == 3) {
  200.         if (ParseFailOption (interp, argv [1], &fail) != TCL_OK)
  201.             return TCL_ERROR;
  202.     } else
  203.         fail = FALSE;
  204.  
  205.     catDesc = catopen (argv [argc - 1], 0);
  206.     if ((catDesc == (nl_catd) -1) && fail)
  207.         return CatOpFailed (interp, "open of message catalog failed");
  208.  
  209.     catDescPtr = Tcl_HandleAlloc (msgCatTblPtr, interp->result);
  210.     *catDescPtr = catDesc;
  211.  
  212.     return TCL_OK;
  213. }
  214.  
  215. /*
  216.  *-----------------------------------------------------------------------------
  217.  *
  218.  * Tcl_CatgetsCmd --
  219.  *    Implements the TCL echo command:
  220.  *        catgets catHandle setnum msgnum defaultstr
  221.  *
  222.  * Results:
  223.  *     Standard Tcl results.
  224.  *
  225.  *-----------------------------------------------------------------------------
  226.  */
  227. static int
  228. Tcl_CatgetsCmd (clientData, interp, argc, argv)
  229.     ClientData  clientData;
  230.     Tcl_Interp *interp;
  231.     int         argc;
  232.     char      **argv;
  233. {
  234.     nl_catd   *catDescPtr;
  235.     int        msgSetNum, msgNum;
  236.     char      *localMsg;
  237.  
  238.     if (argc != 5) {
  239.         Tcl_AppendResult (interp, argv [0], " catHandle setnum msgnum ",
  240.                           "defaultstr", (char *) NULL);
  241.         return TCL_ERROR;
  242.     }
  243.     catDescPtr = Tcl_HandleXlate (interp, msgCatTblPtr, argv [1]);
  244.     if (catDescPtr == NULL)
  245.         return TCL_ERROR;
  246.     if (Tcl_GetInt (interp, argv [2], &msgSetNum) != TCL_OK)
  247.         return TCL_ERROR;
  248.     if (Tcl_GetInt (interp, argv [3], &msgNum) != TCL_OK)
  249.         return TCL_ERROR;
  250.  
  251.     localMsg = catgets (*catDescPtr, msgSetNum, msgNum, argv [4]);
  252.  
  253.     Tcl_SetResult (interp, localMsg, TCL_VOLATILE);
  254.     return TCL_OK;
  255. }
  256.  
  257. /*
  258.  *-----------------------------------------------------------------------------
  259.  *
  260.  * Tcl_CatcloseCmd --
  261.  *    Implements the TCL echo command:
  262.  *        catclose [-fail|-nofail] catHandle
  263.  *
  264.  * Results:
  265.  *     Standard Tcl results.
  266.  *
  267.  *-----------------------------------------------------------------------------
  268.  */
  269. static int
  270. Tcl_CatcloseCmd (clientData, interp, argc, argv)
  271.     ClientData  clientData;
  272.     Tcl_Interp *interp;
  273.     int         argc;
  274.     char      **argv;
  275. {
  276.     int      fail;
  277.     nl_catd *catDescPtr;
  278.  
  279.     if ((argc < 2) || (argc > 3)) {
  280.         Tcl_AppendResult (interp, argv [0], " [-fail|-nofail] catHandle",
  281.                           (char *) NULL);
  282.         return TCL_ERROR;
  283.     }
  284.     if (argc == 3) {
  285.         if (ParseFailOption (interp, argv [1], &fail) != TCL_OK)
  286.             return TCL_ERROR;
  287.     } else
  288.         fail = FALSE;
  289.  
  290.     catDescPtr = Tcl_HandleXlate (interp, msgCatTblPtr, argv [argc - 1]);
  291.     if (catDescPtr == NULL)
  292.         return TCL_ERROR;
  293.  
  294.     if ((catclose (*catDescPtr) < 0) && fail)
  295.         return CatOpFailed (interp, "close of message catalog failed");
  296.  
  297.     Tcl_HandleFree (msgCatTblPtr, catDescPtr);
  298.     return TCL_OK;
  299. }
  300.  
  301. /*
  302.  *-----------------------------------------------------------------------------
  303.  *
  304.  *  MsgCatCleanUp --
  305.  *      Decrements the use count on the globals when a command is deleted.
  306.  *      If it goes to zero, all resources are released.      
  307.  *
  308.  *-----------------------------------------------------------------------------
  309.  */
  310. static void
  311. MsgCatCleanUp (clientData)
  312.     ClientData clientData;
  313. {
  314.     nl_catd *catDescPtr;
  315.     int      walkKey;
  316.     
  317.     if (Tcl_HandleTblUseCount (msgCatTblPtr, -1) > 0)
  318.         return;
  319.  
  320.     walkKey = -1;
  321.     while ((catDescPtr = Tcl_HandleWalk (msgCatTblPtr, &walkKey)) != NULL)
  322.         catclose (*catDescPtr);
  323.  
  324.     Tcl_HandleTblRelease (msgCatTblPtr);
  325. }
  326.  
  327. /*
  328.  *-----------------------------------------------------------------------------
  329.  *
  330.  *  Tcl_InitMsgCat --
  331.  *      Initialize the Tcl XPG/3 message catalog support faility.
  332.  *
  333.  *-----------------------------------------------------------------------------
  334.  */
  335. void
  336. Tcl_InitMsgCat (interp)
  337.     Tcl_Interp *interp;
  338. {
  339.  
  340.     if (msgCatTblPtr == NULL)
  341.         msgCatTblPtr = Tcl_HandleTblInit ("msgcat", sizeof (nl_catd), 6);
  342.  
  343.     (void) Tcl_HandleTblUseCount (msgCatTblPtr, 2);  /* 3 commands total */
  344.  
  345.     /*
  346.      * Initialize the commands.
  347.      */
  348.  
  349.     Tcl_CreateCommand (interp, "catopen", Tcl_CatopenCmd, 
  350.                        (ClientData)NULL, MsgCatCleanUp);
  351.     Tcl_CreateCommand (interp, "catgets", Tcl_CatgetsCmd, 
  352.                        (ClientData)NULL, MsgCatCleanUp);
  353.     Tcl_CreateCommand (interp, "catclose", Tcl_CatcloseCmd,
  354.                        (ClientData)NULL, MsgCatCleanUp);
  355. }
  356.  
  357.