home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / lib / Xt / Varargs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-13  |  14.2 KB  |  495 lines

  1. /* $XConsortium: Varargs.c,v 1.24 91/06/13 18:00:58 converse Exp $ */
  2.  
  3. /*
  4.  
  5. Copyright 1985, 1986, 1987, 1988, 1989 by the
  6. Massachusetts Institute of Technology
  7.  
  8. Permission to use, copy, modify, and distribute this
  9. software and its documentation for any purpose and without
  10. fee is hereby granted, provided that the above copyright
  11. notice appear in all copies and that both that copyright
  12. notice and this permission notice appear in supporting
  13. documentation, and that the name of M.I.T. not be used in
  14. advertising or publicity pertaining to distribution of the
  15. software without specific, written prior permission.
  16. M.I.T. makes no representations about the suitability of
  17. this software for any purpose.  It is provided "as is"
  18. without express or implied warranty.
  19.  
  20. */
  21.  
  22. #include "IntrinsicI.h"
  23. #include "VarargsI.h"
  24. #include "StringDefs.h"
  25.  
  26. static String XtNxtConvertVarToArgList = "xtConvertVarToArgList";
  27.  
  28. /*
  29.  *    Given a nested list, _XtCountNestedList() returns counts of the
  30.  *    total number of attribute-value pairs and the count of those
  31.  *    attributes that are typed. The list is counted recursively.
  32.  */
  33. static  void
  34. _XtCountNestedList(avlist, total_count, typed_count)
  35.     XtTypedArgList  avlist;
  36.     int             *total_count;
  37.     int             *typed_count;
  38. {
  39.     for (; avlist->name != NULL; avlist++) {
  40.         if (strcmp(avlist->name, XtVaNestedList) == 0) {
  41.             _XtCountNestedList((XtTypedArgList)avlist->value, total_count,
  42.                            typed_count);
  43.         } else {
  44.             if (avlist->type != NULL) {
  45.                 ++(*typed_count);
  46.             }
  47.             ++(*total_count);
  48.         }
  49.     }    
  50. }
  51.  
  52.  
  53. /*
  54.  *    Given a variable length attribute-value list, _XtCountVaList()
  55.  *    returns counts of the total number of attribute-value pairs,
  56.  *    and the count of the number of those attributes that are typed.
  57.  *    The list is counted recursively.
  58.  */
  59. #if NeedFunctionPrototypes
  60. void
  61. _XtCountVaList(va_list var, int* total_count, int* typed_count)
  62. #else
  63. void
  64. _XtCountVaList(var, total_count, typed_count)
  65.     va_list     var;
  66.     int         *total_count;
  67.     int         *typed_count;
  68. #endif
  69. {
  70.     String          attr;
  71.     
  72.     *total_count = 0;
  73.     *typed_count = 0;
  74.  
  75.     for(attr = va_arg(var, String) ; attr != NULL;
  76.                         attr = va_arg(var, String)) {
  77.         if (strcmp(attr, XtVaTypedArg) == 0) {
  78.             va_arg(var, String);
  79.             va_arg(var, String);
  80.             va_arg(var, XtArgVal);
  81.             va_arg(var, int);
  82.             ++(*total_count);
  83.             ++(*typed_count);
  84.         } else if (strcmp(attr, XtVaNestedList) == 0) {
  85.             _XtCountNestedList(va_arg(var, XtTypedArgList), total_count,
  86.                 typed_count);
  87.         } else {
  88.             va_arg(var, XtArgVal);
  89.             ++(*total_count);
  90.     }
  91.     }
  92. }
  93.  
  94.  
  95. /* 
  96.  *   Given a variable length attribute-value list, XtVaCreateArgsList()
  97.  *   constructs an attribute-value list of type XtTypedArgList and 
  98.  *   returns the list.
  99.  */
  100. #if NeedVarargsPrototypes
  101. XtVarArgsList
  102. XtVaCreateArgsList(XtPointer unused, ...)
  103. #else
  104. /*ARGSUSED*/
  105. /*VARARGS1*/
  106. XtVarArgsList XtVaCreateArgsList(unused, va_alist)
  107.     XtPointer unused;
  108.     va_dcl
  109. #endif
  110. {
  111.     va_list var;
  112.     XtTypedArgList  avlist;
  113.     int            count = 0;
  114.     String        attr;
  115.  
  116.     /*
  117.      * Count the number of attribute-value pairs in the list.
  118.      * Note: The count is required only to allocate enough space to store
  119.      * the list. Therefore nested lists are not counted recursively.
  120.      */
  121.     Va_start(var,unused);
  122.     for(attr = va_arg(var, String) ; attr != NULL;
  123.                         attr = va_arg(var, String)) {
  124.         ++count;
  125.         if (strcmp(attr, XtVaTypedArg) == 0) {
  126.             va_arg(var, String);
  127.             va_arg(var, String);
  128.             va_arg(var, XtArgVal);
  129.             va_arg(var, int);
  130.         } else {
  131.             va_arg(var, XtArgVal);
  132.         }
  133.     }
  134.     va_end(var);
  135.  
  136.     Va_start(var,unused);
  137.     avlist = _XtVaCreateTypedArgList(var, count);
  138.     va_end(var);
  139.     return (XtVarArgsList)avlist;
  140. }
  141.  
  142.  
  143. #if NeedFunctionPrototypes
  144. XtTypedArgList _XtVaCreateTypedArgList(va_list var, register int count)
  145. #else
  146. XtTypedArgList _XtVaCreateTypedArgList(var, count)
  147.     va_list            var;     
  148.     register int    count;
  149. #endif
  150. {
  151.     String        attr;
  152.     XtTypedArgList  avlist;
  153.  
  154.     avlist = (XtTypedArgList)
  155.         XtCalloc((int)count + 1, (unsigned)sizeof(XtTypedArg));
  156.  
  157.     for(attr = va_arg(var, String), count = 0; attr != NULL; 
  158.         attr = va_arg(var, String)) {
  159.     if (strcmp(attr, XtVaTypedArg) == 0) {
  160.         avlist[count].name = va_arg(var, String);
  161.         avlist[count].type = va_arg(var, String);
  162.         avlist[count].value = va_arg(var, XtArgVal);
  163.         avlist[count].size = va_arg(var, int);
  164.     } else {
  165.         avlist[count].name = attr;
  166.         avlist[count].type = NULL;
  167.         avlist[count].value = va_arg(var, XtArgVal);
  168.     }
  169.     ++count;
  170.     }
  171.     avlist[count].name = NULL;
  172.  
  173.     return avlist;
  174. }
  175.  
  176.  
  177. /*
  178.  *    _XtTypedArgToArg() invokes a resource converter to convert the
  179.  *    passed typed arg into a name/value pair and stores the name/value
  180.  *    pair in the passed Arg structure. It returns 1 if the conversion
  181.  *    succeeded and 0 if the conversion failed.
  182.  */
  183. static int
  184. _XtTypedArgToArg(widget, typed_arg, arg_return, resources, num_resources)
  185.     Widget              widget;
  186.     XtTypedArgList      typed_arg;
  187.     ArgList             arg_return;
  188.     XtResourceList      resources;
  189.     Cardinal            num_resources;
  190. {     
  191.     String              to_type = NULL;
  192.     XrmValue            from_val, to_val;
  193.     register int        i;
  194.       
  195.  
  196.     if (widget == NULL) {
  197.         XtAppWarningMsg(XtWidgetToApplicationContext(widget),
  198.             "nullWidget", XtNxtConvertVarToArgList, XtCXtToolkitError,
  199.         "XtVaTypedArg conversion needs non-NULL widget handle",
  200.             (String *)NULL, (Cardinal *)NULL);
  201.         return(0);
  202.     }
  203.        
  204.     /* again we assume that the XtResourceList is un-compiled */
  205.  
  206.     for (i = 0; i < num_resources; i++) {
  207.         if (StringToName(typed_arg->name) ==
  208.             StringToName(resources[i].resource_name)) {
  209.             to_type = resources[i].resource_type;
  210.             break;
  211.         }
  212.     }
  213.  
  214.     if (to_type == NULL) {
  215.         XtAppWarningMsg(XtWidgetToApplicationContext(widget),
  216.             "unknownType", XtNxtConvertVarToArgList, XtCXtToolkitError,
  217.             "Unable to find type of resource for conversion",
  218.             (String *)NULL, (Cardinal *)NULL);
  219.         return(0);
  220.     }
  221.        
  222.     to_val.addr = NULL;
  223.     from_val.size = typed_arg->size;
  224.     if ((strcmp(typed_arg->type, XtRString) == 0) ||
  225.             (typed_arg->size > sizeof(XtArgVal))) {
  226.         from_val.addr = (XPointer)typed_arg->value;
  227.     } else {
  228.             from_val.addr = (XPointer)&typed_arg->value;
  229.     }
  230.        
  231.     XtConvert(widget, typed_arg->type, &from_val, to_type, &to_val);
  232.  
  233.     if (to_val.addr == NULL) {
  234.         XtAppWarningMsg(XtWidgetToApplicationContext(widget),
  235.             "conversionFailed", XtNxtConvertVarToArgList, XtCXtToolkitError,
  236.             "Type conversion failed", (String *)NULL, (Cardinal *)NULL);
  237.         return(0);
  238.     }
  239.  
  240.     arg_return->name = typed_arg->name;
  241.  
  242.     if (strcmp(to_type, XtRString) == 0) {
  243.     arg_return->value = (XtArgVal) to_val.addr;
  244.     }
  245.     else {
  246.     if (to_val.size == sizeof(long))
  247.         arg_return->value = (XtArgVal) *(long *)to_val.addr;
  248.     else if (to_val.size == sizeof(short))
  249.         arg_return->value = (XtArgVal) *(short *)to_val.addr;
  250.     else if (to_val.size == sizeof(char))
  251.         arg_return->value = (XtArgVal) *(char *)to_val.addr;
  252.     else if (to_val.size == sizeof(XtArgVal))
  253.         arg_return->value = *(XtArgVal *)to_val.addr;
  254.     }
  255.        
  256.     return(1);
  257. }
  258.  
  259.  
  260. /*
  261.  *    _XtNestedArgtoArg() converts the passed nested list into
  262.  *    an ArgList/count.
  263.  */
  264. static int
  265. _XtNestedArgtoArg(widget, avlist, args, resources, num_resources)
  266.     Widget              widget;
  267.     XtTypedArgList      avlist;
  268.     ArgList             args;
  269.     XtResourceList      resources;
  270.     Cardinal            num_resources;
  271. {
  272.     int         count = 0;
  273.  
  274.     for (; avlist->name != NULL; avlist++) {
  275.         if (avlist->type != NULL) {
  276.             /* If widget is NULL, the typed arg is ignored */
  277.             if (widget != NULL) {
  278.                 /* this is a typed arg */
  279.                 count += _XtTypedArgToArg(widget, avlist, (args+count),
  280.                              resources, num_resources);
  281.             }
  282.         } else if (strcmp(avlist->name, XtVaNestedList) == 0) {
  283.             count += _XtNestedArgtoArg(widget, (XtTypedArgList)avlist->value,
  284.                         (args+count), resources, num_resources);
  285.         } else {
  286.             (args+count)->name = avlist->name;
  287.             (args+count)->value = avlist->value;
  288.             ++count;
  289.         }
  290.     }
  291.  
  292.     return(count);
  293. }
  294.  
  295. static void        GetResources();
  296.  
  297.  
  298. /* 
  299.  *    Given a variable argument list, _XtVaToArgList() returns the 
  300.  *    equivalent ArgList and count. _XtVaToArgList() handles nested 
  301.  *    lists and typed arguments. 
  302.  */
  303. #if NeedFunctionPrototypes
  304. void
  305. _XtVaToArgList(
  306.     Widget        widget,
  307.     va_list         var,
  308.     int            max_count,
  309.     ArgList        *args_return,
  310.     Cardinal        *num_args_return)
  311. #else
  312. void
  313. _XtVaToArgList(widget, var, max_count, args_return, num_args_return)
  314.     Widget        widget;
  315.     va_list         var;
  316.     int            max_count;
  317.     ArgList        *args_return;
  318.     Cardinal        *num_args_return;
  319. #endif
  320. {
  321.     String        attr;
  322.     int            count = 0;
  323.     ArgList        args = (ArgList)NULL;
  324.     XtTypedArg        typed_arg;
  325.     XtResourceList    resources = (XtResourceList)NULL;
  326.     Cardinal        num_resources;
  327.     Boolean        fetched_resource_list = False;
  328.  
  329.     if (max_count  == 0) {
  330.     *num_args_return = 0;
  331.     *args_return = (ArgList)NULL;
  332.     return;
  333.     }
  334.  
  335.  
  336.     args = (ArgList)XtMalloc((unsigned)(max_count * sizeof(Arg)));
  337.  
  338.     for(attr = va_arg(var, String) ; attr != NULL;
  339.             attr = va_arg(var, String)) {
  340.     if (strcmp(attr, XtVaTypedArg) == 0) {
  341.         typed_arg.name = va_arg(var, String);
  342.         typed_arg.type = va_arg(var, String);
  343.         typed_arg.value = va_arg(var, XtArgVal);
  344.         typed_arg.size = va_arg(var, int);
  345.  
  346.         /* if widget is NULL, typed args are ignored */
  347.         if (widget != NULL) {
  348.         if (!fetched_resource_list) {
  349.             GetResources(widget, &resources, &num_resources);
  350.             fetched_resource_list = True;
  351.         }
  352.         count += _XtTypedArgToArg(widget, &typed_arg, &args[count],
  353.                  resources, num_resources);
  354.         }
  355.     } else if (strcmp(attr, XtVaNestedList) == 0) {
  356.         if (widget != NULL || !fetched_resource_list) {
  357.         GetResources(widget, &resources, &num_resources);
  358.         fetched_resource_list = True;
  359.         }
  360.  
  361.         count += _XtNestedArgtoArg(widget, va_arg(var, XtTypedArgList),
  362.             &args[count], resources, num_resources);
  363.     } else {
  364.         args[count].name = attr;
  365.         args[count].value = va_arg(var, XtArgVal);
  366.         count ++;
  367.     }
  368.     }
  369.  
  370.     XtFree((XtPointer)resources);
  371.  
  372.     *num_args_return = (Cardinal)count;
  373.     *args_return = (ArgList)args;
  374. }
  375.  
  376. /*    Function Name: GetResources
  377.  *    Description: Retreives the normal and constraint resources
  378.  *                   for this widget.
  379.  *    Arguments: widget - the widget.
  380.  * RETURNED        res_list - the list of resource for this widget
  381.  * RETURNED        number - the number of resources in the above list.
  382.  *    Returns: none
  383.  */
  384.  
  385. static void
  386. GetResources(widget, res_list, number)
  387. Widget widget;
  388. XtResourceList * res_list;
  389. Cardinal * number;
  390. {
  391.     Widget parent = XtParent(widget);
  392.  
  393.     XtInitializeWidgetClass(XtClass(widget));
  394.     XtGetResourceList(XtClass(widget), res_list, number);
  395.     
  396.     /* assert: !XtIsShell(w) => (XtParent(w) != NULL) */
  397.     if (!XtIsShell(widget) && XtIsConstraint(parent)) {
  398.     XtResourceList res, constraint, cons_top;
  399.     Cardinal num_constraint, temp;
  400.  
  401.     XtGetConstraintResourceList(XtClass(parent), &constraint, 
  402.                     &num_constraint);
  403.  
  404.     cons_top = constraint;
  405.     *res_list = (XtResourceList) XtRealloc((char*)*res_list, 
  406.                            ((*number + num_constraint) * 
  407.                         sizeof(XtResource)));
  408.  
  409.     for (temp= num_constraint, res= *res_list + *number; temp != 0; temp--)
  410.         *res++ = *constraint++;
  411.  
  412.     *number += num_constraint;
  413.     XtFree( (XtPointer) cons_top);
  414.     }
  415. }
  416.  
  417. static int _XtNestedArgtoTypedArg(args, avlist) 
  418.     XtTypedArgList      args;
  419.     XtTypedArgList      avlist;
  420. {    
  421.     int         count = 0;
  422.      
  423.     for (; avlist->name != NULL; avlist++) { 
  424.         if (avlist->type != NULL) { 
  425.             (args+count)->name = avlist->name; 
  426.             (args+count)->type = avlist->type; 
  427.             (args+count)->size = avlist->size;
  428.             (args+count)->value = avlist->value;
  429.             ++count; 
  430.         } else if(strcmp(avlist->name, XtVaNestedList) == 0) {             
  431.             count += _XtNestedArgtoTypedArg((args+count),  
  432.                             (XtTypedArgList)avlist->value); 
  433.         } else {                             
  434.             (args+count)->name = avlist->name; 
  435.         (args+count)->type = NULL;
  436.             (args+count)->value = avlist->value; 
  437.             ++count;
  438.         }                                     
  439.     }         
  440.     return(count);
  441. }
  442.  
  443.  
  444. /*
  445.  *    Given a variable argument list, _XtVaToTypedArgList() returns 
  446.  *    the equivalent TypedArgList. _XtVaToTypedArgList() handles nested
  447.  *    lists.
  448.  *    Note: _XtVaToTypedArgList() does not do type conversions.
  449.  */
  450. #if NeedFunctionPrototypes
  451. void
  452. _XtVaToTypedArgList(
  453.     va_list             var,
  454.     int            max_count,
  455.     XtTypedArgList       *args_return,
  456.     Cardinal            *num_args_return)
  457. #else
  458. void
  459. _XtVaToTypedArgList(var, max_count, args_return, num_args_return)
  460.     va_list             var;
  461.     int            max_count;
  462.     XtTypedArgList       *args_return;
  463.     Cardinal            *num_args_return;
  464. #endif
  465. {
  466.     XtTypedArgList    args = NULL;
  467.     String              attr;
  468.     int            count;
  469.  
  470.     args = (XtTypedArgList)
  471.     XtMalloc((unsigned)(max_count * sizeof(XtTypedArg))); 
  472.  
  473.     for(attr = va_arg(var, String), count = 0 ; attr != NULL;
  474.             attr = va_arg(var, String)) {
  475.         if (strcmp(attr, XtVaTypedArg) == 0) {
  476.         args[count].name = va_arg(var, String);
  477.         args[count].type = va_arg(var, String);
  478.         args[count].value = va_arg(var, XtArgVal);
  479.         args[count].size = va_arg(var, int);
  480.         ++count;
  481.     } else if (strcmp(attr, XtVaNestedList) == 0) {
  482.            count += _XtNestedArgtoTypedArg(&args[count], 
  483.             va_arg(var, XtTypedArgList));
  484.     } else {
  485.         args[count].name = attr;
  486.         args[count].type = NULL;
  487.         args[count].value = va_arg(var, XtArgVal);
  488.         ++count;
  489.     }
  490.     }
  491.  
  492.     *args_return = args;
  493.     *num_args_return = count;
  494. }
  495.