home *** CD-ROM | disk | FTP | other *** search
/ Chip 2000 May / Chip_2000-05_cd1.bin / zkuste / Perl / ActivePerl-5.6.0.613.msi / 䆊䌷䈹䈙䏵-䞅䞆䞀㡆䞃䄦䠥 / _e9da619a6e0b83f0e15a069ddba89cec < prev    next >
Text File  |  2000-03-23  |  27KB  |  553 lines

  1.  
  2. <HTML>
  3. <HEAD>
  4. <TITLE>Tk2portableTk - how to make your B<Tk> source portable to other
  5. interpreted languages.</TITLE>
  6. <LINK REL="stylesheet" HREF="../../../Active.css" TYPE="text/css">
  7. <LINK REV="made" HREF="mailto:">
  8. </HEAD>
  9.  
  10. <BODY>
  11. <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
  12. <TR><TD CLASS=block VALIGN=MIDDLE WIDTH=100% BGCOLOR="#cccccc">
  13. <STRONG><P CLASS=block> Tk2portableTk - how to make your B<Tk> source portable to other
  14. interpreted languages.</P></STRONG>
  15. </TD></TR>
  16. </TABLE>
  17.  
  18. <A NAME="__index__"></A>
  19. <!-- INDEX BEGIN -->
  20.  
  21. <UL>
  22.  
  23.     <LI><A HREF="#name">NAME</A></LI><LI><A HREF="#supportedplatforms">SUPPORTED PLATFORMS</A></LI>
  24.  
  25.     <LI><A HREF="#author">Author</A></LI>
  26.     <LI><A HREF="#description">DESCRIPTION</A></LI>
  27.     <LI><A HREF="#structure of ptk, porting your code">Structure of <STRONG>pTk</STRONG>, porting your code</A></LI>
  28.     <LI><A HREF="#portabletk api"><STRONG>PortableTk</STRONG> API</A></LI>
  29.     <UL>
  30.  
  31.         <LI><A HREF="#checking what you are running under">Checking what you are running under</A></LI>
  32.         <LI><A HREF="#new types of configuration options">New types of configuration options</A></LI>
  33.         <LI><A HREF="#language data">Language data</A></LI>
  34.         <LI><A HREF="#conversion">Conversion</A></LI>
  35.         <LI><A HREF="#callbacks">Callbacks</A></LI>
  36.         <LI><A HREF="#setting variables">Setting variables</A></LI>
  37.         <LI><A HREF="#language functions">Language functions</A></LI>
  38.         <LI><A HREF="#translation of some tcl functions">Translation of some TCL functions</A></LI>
  39.     </UL>
  40.  
  41.     <LI><A HREF="#translation back to tcl">Translation back to TCL</A></LI>
  42.     <UL>
  43.  
  44.         <LI><A HREF="#new types of events ">New types of events ????</A></LI>
  45.     </UL>
  46.  
  47.     <LI><A HREF="#checking for trouble">Checking for trouble</A></LI>
  48.     <LI><A HREF="#additional api">Additional API</A></LI>
  49.     <UL>
  50.  
  51.         <LI><A HREF="#listfactory"><CODE>ListFactory</CODE></A></LI>
  52.         <LI><A HREF="#dstrings">DStrings</A></LI>
  53.         <LI><A HREF="#accessing args">Accessing <CODE>Arg</CODE>s</A></LI>
  54.         <LI><A HREF="#assigning numbers to args">Assigning numbers to <CODE>Arg</CODE>s</A></LI>
  55.         <LI><A HREF="#creating new args">Creating new <CODE>Arg</CODE>s</A></LI>
  56.         <LI><A HREF="#evaluating a list">Evaluating a list</A></LI>
  57.         <LI><A HREF="#getting result as arg">Getting result as <CODE>Arg</CODE></A></LI>
  58.     </UL>
  59.  
  60. </UL>
  61. <!-- INDEX END -->
  62.  
  63. <HR>
  64. <P>
  65. <H1><A NAME="name">NAME</A></H1>
  66. <P>Tk2portableTk - how to make your <STRONG>Tk</STRONG> source portable to other
  67. interpreted languages.</P>
  68. <P>
  69. <HR>
  70. <H1><A NAME="supportedplatforms">SUPPORTED PLATFORMS</A></H1>
  71. <UL>
  72. <LI>Linux</LI>
  73. <LI>Solaris</LI>
  74. <LI>Windows</LI>
  75. </UL>
  76. <HR>
  77. <H1><A NAME="author">Author</A></H1>
  78. <P>Ilya Zakharevich <<A HREF="mailto:ilya@math.ohio-state.edu">ilya@math.ohio-state.edu</A>>  has contributed most of
  79. this document. Many thanks.</P>
  80. <P>
  81. <HR>
  82. <H1><A NAME="description">DESCRIPTION</A></H1>
  83. <P><STRONG>PortableTk</STRONG> is an attempt to make <STRONG>Tk</STRONG> useful from other
  84. languages. Currently tk4.0 runs under Perl using this
  85. approach. Below, <EM>Lang</EM> is the notation for an external language to
  86. which <STRONG>PortableTk</STRONG> glues <STRONG>Tk</STRONG> code.</P>
  87. <P>The main problem with using the code developed for <STRONG>TCL</STRONG> with
  88. different languages is the absence of data types: almost anything is
  89. <CODE>char*</CODE>. It makes automatic translation hopeless. However, if you
  90. <CODE>typedef</CODE> several new symbols to be <CODE>char*</CODE>, you can still use your
  91. code in <STRONG>TCL</STRONG>, <EM>and</EM> it will make the automatic translation
  92. possible.</P>
  93. <P>Another problem with the approach that ``everything is a string'' is
  94. impossibility to have a result that says ``NotApplicable'' without
  95. setting an error. Thus different <STRONG>Tk</STRONG> command return different string
  96. values that mean ``error happened'', like <CODE>""</CODE>, <CODE>" "</CODE> or
  97. <CODE>"??"</CODE>. Other languages can be more flexible, so in <STRONG>portableTk</STRONG> you
  98. should inform the compiler that what you want to return means ``error''
  99. (see <A HREF="#setting variables">Setting variables</A>).</P>
  100. <P>Currently <STRONG>PortableTk</STRONG> uses several different approachs
  101. to simplify translation: several <STRONG>TCL</STRONG> functions that are especially
  102. dangerous to use are undefined, so you can easily find places that
  103. need to be updated to use Language-independent functions based on
  104. compiler warnings.  Eventually a way to use these Language-independent
  105. functions under proper <STRONG>TCL</STRONG> will be also provided.  The end of this
  106. document provides a starting point for such a project.</P>
  107. <P>
  108. <HR>
  109. <H1><A NAME="structure of ptk, porting your code">Structure of <STRONG>pTk</STRONG>, porting your code</A></H1>
  110. <P><STRONG>pTk</STRONG>, that is a port of <STRONG>Tk</STRONG>, is very special with respect to porting
  111. of other code to <STRONG>portableTk</STRONG>. The problem is that currently there is
  112. very little hope to merge the modifications back into <STRONG>Tk</STRONG>, so a
  113. special strategy is needed to maintain this port. Do not use this
  114. strategy to port your own code.</P>
  115. <P><STRONG>pTk</STRONG> is produced from <STRONG>Tk</STRONG> via a two-step process: first, some
  116. manual editing (the result is in the subdirectory <CODE>mTk</CODE>), and second,
  117. automatic conversion by the <CODE>munge</CODE> script (written in Perl). Thus the
  118. subdirectory <CODE>pTk/mTk</CODE> contains code with minimal possible difference
  119. from the virgin <STRONG>Tk</STRONG> code, so it is easier to <CODE>merge(1)</CODE> the
  120. differences between <STRONG>Tk</STRONG> versions into modified code.</P>
  121. <P>It looks like the strategy for a portable code should be exactly
  122. opposite: starting from <STRONG>TCL</STRONG>-based code, apply <CODE>munge</CODE>, and then
  123. hand-edit the resulting code. Probably it is also possible to target
  124. your code to <STRONG>portableTk</STRONG> from scratch, since this will make it
  125. possible to run it under a lot of <EM>Lang</EM>uages.</P>
  126. <P>The only reason anyone would like to look into contents of <CODE>pTk/mTk</CODE>
  127. directory is to find out which constructs are not supported by
  128. <CODE>munge</CODE>. On the other hand, <CODE>pTk</CODE> directory contains code that is
  129. conformant to <STRONG>portableTk</STRONG>, so you can look there to find example code.</P>
  130. <P><CODE>munge</CODE> is the script that converts most common <STRONG>Tk</STRONG> constructs to
  131. their <CODE>portableTk</CODE> equivalent. For your code to qualify, you should
  132. follow <STRONG>Tk</STRONG> conventions on indentation and names of variables, in
  133. particular, the array of arguments for the <CODE>...CmdProc</CODE> should be
  134. called <CODE>argv</CODE>.</P>
  135. <P>For details on what <CODE>munge</CODE> can do, see
  136. <A HREF="#translation of some tcl functions">Translation of some TCL functions</A>.</P>
  137. <P>
  138. <HR>
  139. <H1><A NAME="portabletk api"><STRONG>PortableTk</STRONG> API</A></H1>
  140. <P>
  141. <H2><A NAME="checking what you are running under">Checking what you are running under</A></H2>
  142. <P><STRONG>PortableTk</STRONG> provides a symbol <CODE>????</CODE>. If this symbol is defined,
  143. your source is compiled with it.</P>
  144. <P>
  145. <H2><A NAME="new types of configuration options">New types of configuration options</A></H2>
  146. <P><STRONG>PortableTk</STRONG> defines several new types of configuration options:</P>
  147. <PRE>
  148.  TK_CONFIG_CALLBACK
  149.  TK_CONFIG_LANGARG
  150.  TK_CONFIG_SCALARVAR
  151.  TK_CONFIG_HASHVAR
  152.  TK_CONFIG_ARRAYVAR
  153.  TK_CONFIG_IMAGE</PRE>
  154. <P>You should use them instead of TK_CONFIG_STRING whenever
  155. appropriate. This allows your application to receive a direct
  156. representation of the corresponding resource instead of the string
  157. representation, if this is possible under given language.</P>
  158. <P>???? It looks like <CODE>TK_CONFIG_IMAGE</CODE> and <CODE>TK_CONFIG_SCALARVAR</CODE> set
  159. variables of type <CODE>char*</CODE>.</P>
  160. <P>
  161. <H2><A NAME="language data">Language data</A></H2>
  162. <P>The following data types are defined:</P>
  163. <DL>
  164. <DT><STRONG><A NAME="item_Arg"><CODE>Arg</CODE></A></STRONG><BR>
  165. <DD>
  166. is the main datatype of the language.  This is a type that your C
  167. function gets pointers to for arguments when the corresponding <EM>Lang</EM>
  168. function is called.  The corresponding config type is
  169. <CODE>TK_CONFIG_LANGARG</CODE>.
  170. <P>This is also a type that keeps information about contents of <EM>Lang</EM>
  171. variable.</P>
  172. <P></P>
  173. <DT><STRONG><A NAME="item_Var"><CODE>Var</CODE></A></STRONG><BR>
  174. <DD>
  175. Is a substitute for a <CODE>char *</CODE> that contains name of variable. In
  176. <EM>Lang</EM> it is an object that contains reference to another <EM>Lang</EM>
  177. variable.
  178. <P></P>
  179. <DT><STRONG><A NAME="item_LangResultSave"><CODE>LangResultSave</CODE></A></STRONG><BR>
  180. <DD>
  181. ????
  182. <P></P>
  183. <DT><STRONG><A NAME="item_LangCallback"><CODE>LangCallback</CODE></A></STRONG><BR>
  184. <DD>
  185. <CODE>LangCallback*</CODE> a substitute for a <CODE>char *</CODE> that contains command to
  186. call. The corresponding config type is <CODE>TK_CONFIG_CALLBACK</CODE>.
  187. <P></P>
  188. <DT><STRONG><A NAME="item_LangFreeProc"><CODE>LangFreeProc</CODE></A></STRONG><BR>
  189. <DD>
  190. It is the type that the <CODE>Lang_SplitList</CODE> sets. Before you call it,
  191. declare
  192. <PRE>
  193.     Args *args;
  194.     LangFreeProc *freeProc = NULL;
  195.     ...
  196.     code = Lang_SplitList(interp, value,
  197.         &argc, &args, &freeProc);</PRE>
  198. <P>After you use the split values, call</P>
  199. <PRE>
  200.     if (args != NULL && freeProc) (*freeProc)(argc,args);</PRE>
  201. <P>It is not guaranteed that the <CODE>args</CODE> can survive deletion of <CODE>value</CODE>.</P>
  202. <P></P></DL>
  203. <P>
  204. <H2><A NAME="conversion">Conversion</A></H2>
  205. <P>The following macros and functions are used for conversion between
  206. strings and the additional types:</P>
  207. <PRE>
  208.  LangCallback * LangMakeCallback(Arg)
  209.  Arg LangCallbackArg(LangCallback *)
  210.  char * LangString(Arg)</PRE>
  211. <P>After you use the result of LangCallbackArg(), you should free it with
  212. <CODE>freeProc</CODE> <CODE>LANG_DYNAMIC</CODE> (it is not guaranteed that any change of
  213. <A HREF="#item_Arg"><CODE>Arg</CODE></A> will not be reflected in <LangCallback>, so you cannot do
  214. LangSet...() in between, and you should reset it to <CODE>NULL</CODE> if you
  215. want to do any further assignments to this <A HREF="#item_Arg"><CODE>Arg</CODE></A>).</P>
  216. <P>The following function returns the <A HREF="#item_Arg"><CODE>Arg</CODE></A> that is a reference to <A HREF="#item_Var"><CODE>Var</CODE></A>:</P>
  217. <PRE>
  218.  Arg LangVarArg(Var)</PRE>
  219. <P>???? It is very anti-intuitive, I hope the name is changed.</P>
  220. <PRE>
  221.  int LangCmpCallback(LangCallback *a,Arg b)</PRE>
  222. <P>(currently only a stub), and, at last,</P>
  223. <PRE>
  224.  LangCallback * LangCopyCallback(LangCallback *)</PRE>
  225. <P>
  226. <H2><A NAME="callbacks">Callbacks</A></H2>
  227. <P>Above we have seen the new datatype <A HREF="#item_LangCallback"><CODE>LangCallback</CODE></A> and the
  228. corresponding <EM>Config option</EM>  <CODE>TK_CONFIG_CALLBACK</CODE>. The following
  229. functions are provided for manipulation of <A HREF="#item_LangCallback"><CODE>LangCallback</CODE></A>s:</P>
  230. <PRE>
  231.  void LangFreeCallback(LangCallback *)
  232.  int LangDoCallback(Tcl_Interp *,LangCallback *,
  233.         int result,int argc, char *format,...)</PRE>
  234. <P>The argument <A HREF="../../../lib/Pod/perlfunc.html#item_format"><CODE>format</CODE></A> of <CODE>LangDoCallback</CODE> should contain a string that is
  235. suitable for <A HREF="#item_sprintf"><CODE>sprintf</CODE></A> with optional arguments of <CODE>LangDoCallback</CODE>.
  236. <A HREF="#item_result"><CODE>result</CODE></A> should be false if result of callback is not needed.</P>
  237. <PRE>
  238.  int LangMethodCall(Tcl_Interp *,Arg,char *method,
  239.         int result,int argc,...)</PRE>
  240. <P>????</P>
  241. <P>Conceptually, <CODE>LangCallback*</CODE> is a substitute for ubiquitous <CODE>char *</CODE>
  242. in <STRONG>TCL</STRONG>. So you should use <CODE>LangFreeCallback</CODE> instead of <CODE>ckfree</CODE>
  243. or <CODE>free</CODE> if appropriate.</P>
  244. <P>
  245. <H2><A NAME="setting variables">Setting variables</A></H2>
  246. <PRE>
  247.  void LangFreeArg (Arg, Tcl_FreeProc *freeProc)
  248.  Arg  LangCopyArg (Arg);
  249.  void Tcl_AppendArg (Tcl_Interp *interp, Arg)
  250.  void LangSetString(Arg *, char *s)
  251.  void LangSetDefault(Arg *, char *s)</PRE>
  252. <P>These two are equivalent unless s is an empty string. In this case
  253. <CODE>LangSetDefault</CODE> behaves like <CODE>LangSetString</CODE> with <CODE>s==NULL</CODE>, i.e.,
  254. it sets the current value of the <EM>Lang</EM> variable to be false.</P>
  255. <PRE>
  256.  void LangSetInt(Arg *,int)
  257.  void LangSetDouble(Arg *,double)</PRE>
  258. <P>The <EM>Lang</EM> functions separate uninitialized and initialized data
  259. comparing data with <CODE>NULL</CODE>. So the declaration for an <A HREF="#item_Arg"><CODE>Arg</CODE></A> should
  260. look like</P>
  261. <PRE>
  262.  Arg arg = NULL;</PRE>
  263. <P>if you want to use this <CODE>arg</CODE> with the above functions. After you are
  264. done, you should use <CODE>LangFreeArg</CODE> with <CODE>TCL_DYNAMIC</CODE> as <CODE>freeProc</CODE>.</P>
  265. <P>
  266. <H2><A NAME="language functions">Language functions</A></H2>
  267. <P>Use</P>
  268. <DL>
  269. <DT><STRONG><A NAME="item_LangNull"><CODE>int  LangNull(Arg)</CODE></A></STRONG><BR>
  270. <DD>
  271. to check that an object is false;
  272. <P></P>
  273. <DT><STRONG><A NAME="item_LangStringMatch"><CODE>int  LangStringMatch(char *string, Arg match)</CODE></A></STRONG><BR>
  274. <DD>
  275. ????
  276. <P></P>
  277. <DT><STRONG><A NAME="item_LangExit"><CODE>void LangExit(int)</CODE></A></STRONG><BR>
  278. <DD>
  279. to make a proper shutdown;
  280. <P></P>
  281. <DT><STRONG><A NAME="item_LangEval"><CODE>int LangEval(Tcl_Interp *interp, char *cmd, int global)</CODE></A></STRONG><BR>
  282. <DD>
  283. to call <EM>Lang</EM> <A HREF="../../../lib/Pod/perlfunc.html#item_eval"><CODE>eval</CODE></A>;
  284. <P></P>
  285. <DT><STRONG><A NAME="item_Lang_SetErrorCode"><CODE>void Lang_SetErrorCode(Tcl_Interp *interp,char *code)</CODE></A></STRONG><BR>
  286. <DD>
  287. <DT><STRONG><A NAME="item_Lang_GetErrorCode"><CODE>char *Lang_GetErrorCode(Tcl_Interp *interp)</CODE></A></STRONG><BR>
  288. <DD>
  289. <DT><STRONG><A NAME="item_Lang_GetErrorInfo"><CODE>char *Lang_GetErrorInfo(Tcl_Interp *interp)</CODE></A></STRONG><BR>
  290. <DD>
  291. <DT><STRONG><A NAME="item_LangCloseHandler"><CODE>void LangCloseHandler(Tcl_Interp *interp,Arg arg,FILE *f,Lang_FileCloseProc *proc)</CODE></A></STRONG><BR>
  292. <DD>
  293. currently stubs only;
  294. <P></P>
  295. <DT><STRONG><A NAME="item_LangSaveVar"><CODE>int LangSaveVar(Tcl_Interp *,Arg arg,Var *varPtr,int type)</CODE></A></STRONG><BR>
  296. <DD>
  297. to save the structure <CODE>arg</CODE> into <EM>Lang</EM> variable <CODE>*varPtr</CODE>;
  298. <P></P>
  299. <DT><STRONG><A NAME="item_LangFreeVar"><CODE>void LangFreeVar(Var var)</CODE></A></STRONG><BR>
  300. <DD>
  301. to free the result;
  302. <P></P>
  303. <DT><STRONG><A NAME="item_LangEventCallback"><CODE>int LangEventCallback(Tcl_Interp *,LangCallback *,XEvent *,KeySym)</CODE></A></STRONG><BR>
  304. <DD>
  305. ????
  306. <P></P>
  307. <DT><STRONG><A NAME="item_LangEventHook"><CODE>int LangEventHook(int flags)</CODE></A></STRONG><BR>
  308. <DD>
  309. <DT><STRONG><A NAME="item_LangBadFile"><CODE>void LangBadFile(int fd)</CODE></A></STRONG><BR>
  310. <DD>
  311. <DT><STRONG><A NAME="item_LangCmpConfig"><CODE>int LangCmpConfig(char *spec, char *arg, size_t length)</CODE></A></STRONG><BR>
  312. <DD>
  313. unsupported????;
  314. <P></P>
  315. <DT><STRONG><A NAME="item_Tcl_AppendArg"><CODE>void Tcl_AppendArg (Tcl_Interp *interp, Arg)</CODE></A></STRONG><BR>
  316. <DD>
  317. </DL>
  318. <P>Another useful construction is</P>
  319. <PRE>
  320.  Arg variable = LangFindVar(interp, Tk_Window tkwin, char *name);</PRE>
  321. <P>After using the above function, you should call</P>
  322. <PRE>
  323.  LangFreeVar(Var variable);</PRE>
  324. <P>???? Note discrepancy in types!</P>
  325. <P>If you want to find the value of a variable (of type <A HREF="#item_Arg"><CODE>Arg</CODE></A>) given the
  326. variable name, use <CODE>Tcl_GetVar(interp, varName, flags)</CODE>. If you are
  327. interested in the string value of this variable, use
  328. <CODE>LangString(Tcl_GetVar(...))</CODE>.</P>
  329. <P>To get a <STRONG>C</STRONG> array of <A HREF="#item_Arg"><CODE>Arg</CODE></A> of length <CODE>n</CODE>, use</P>
  330. <PRE>
  331.     Arg *args = LangAllocVec(n);
  332.     ...
  333.     LangFreeVec(n,args);</PRE>
  334. <P>You can set the values of the <A HREF="#item_Arg"><CODE>Arg</CODE></A>s using <CODE>LangSet...</CODE> functions,
  335. and get string value using <CODE>LangString</CODE>.</P>
  336. <P>If you want to merge an array of <A HREF="#item_Arg"><CODE>Arg</CODE></A>s into one <A HREF="#item_Arg"><CODE>Arg</CODE></A> (that will
  337. be an array variable), use</P>
  338. <PRE>
  339.     result = Tcl_Merge(listLength, list);</PRE>
  340. <P>
  341. <H2><A NAME="translation of some tcl functions">Translation of some TCL functions</A></H2>
  342. <P>We mark items that can be dealt with by <CODE>munge</CODE> by <EM>Autoconverted</EM>.</P>
  343. <DL>
  344. <DT><STRONG><A NAME="item_Tcl_AppendResult"><CODE>Tcl_AppendResult</CODE></A></STRONG><BR>
  345. <DD>
  346. does not take <CODE>(char*)NULL</CODE>, but <CODE>NULL</CODE> as delimiter. <EM>Autoconverted</EM>.
  347. <P></P>
  348. <DT><STRONG><A NAME="item_Tcl_CreateCommand%2C_Tcl_DeleteCommand"><CODE>Tcl_CreateCommand</CODE>, <CODE>Tcl_DeleteCommand</CODE></A></STRONG><BR>
  349. <DD>
  350. <CODE>Tk_CreateWidget</CODE>, <CODE>Tk_DeleteWidget</CODE>, the second argument is the
  351. window itself, not the pathname. <EM>Autoconverted</EM>.
  352. <P></P>
  353. <DT><STRONG><A NAME="item_sprintf"><CODE>sprintf(interp->result, "%d %d %d %d",...)</CODE></A></STRONG><BR>
  354. <DD>
  355. <CODE>Tcl_IntResults(interp,4,0,...)</CODE>. <EM>Autoconverted</EM>.
  356. <P></P>
  357. <DT><STRONG><A NAME="item_result"><CODE>interp->result = "1";</CODE></A></STRONG><BR>
  358. <DD>
  359. <CODE>Tcl_SetResult(interp,"1", TCL_STATIC)</CODE>. <EM>Autoconverted</EM>.
  360. <P></P>
  361. <DT><STRONG>Reading <CODE>interp->result</CODE></STRONG><BR>
  362. <DD>
  363. <CODE>Tcl_GetResult(interp)</CODE>. <EM>Autoconverted</EM>.
  364. <P></P>
  365. <DT><STRONG><A NAME="item_Tk_PathName"><CODE>interp->result = Tk_PathName(textPtr->tkwin);</CODE></A></STRONG><BR>
  366. <DD>
  367. <CODE>Tk_WidgetResult(interp,textPtr->tkwin)</CODE>. <EM>Autoconverted</EM>.
  368. <P></P>
  369. <DT><STRONG><A NAME="item_Sequence_Tcl_PrintDouble%2C_Tcl_PrintDouble%2C_%2E">Sequence <CODE>Tcl_PrintDouble, Tcl_PrintDouble, ..., Tcl_AppendResult</CODE></A></STRONG><BR>
  370. <DD>
  371. Use a single command
  372. <PRE>
  373.  void Tcl_DoubleResults(Tcl_Interp *interp, int append,
  374.         int argc,...);</PRE>
  375. <P><CODE>append</CODE> governs whether it is required to clear the result first.</P>
  376. <P>A similar command for <A HREF="../../../lib/Pod/perlfunc.html#item_int"><CODE>int</CODE></A> arguments is <CODE>Tcl_IntResults</CODE>.</P>
  377. <P></P>
  378. <DT><STRONG><A NAME="item_Tcl_SplitList"><CODE>Tcl_SplitList</CODE></A></STRONG><BR>
  379. <DD>
  380. Use <CODE>Lang_SplitList</CODE> (see the description above).
  381. <P></P></DL>
  382. <P>
  383. <HR>
  384. <H1><A NAME="translation back to tcl">Translation back to TCL</A></H1>
  385. <P>To use your <STRONG>portableTk</STRONG> program with <STRONG>TCL</STRONG>, put</P>
  386. <PRE>
  387.  #include "ptcl.h"</PRE>
  388. <P><EM>before</EM> inclusion of <CODE>tk.h</CODE>, and link the resulting code with
  389. <CODE>ptclGlue.c</CODE>.</P>
  390. <P>These files currently implement the following:</P>
  391. <DL>
  392. <DT><STRONG><A NAME="item_Additional_config_types%3A">Additional config types:</A></STRONG><BR>
  393. <DD>
  394. <PRE>
  395.  TK_CONFIG_CALLBACK
  396.  TK_CONFIG_LANGARG
  397.  TK_CONFIG_SCALARVAR
  398.  TK_CONFIG_HASHVAR
  399.  TK_CONFIG_ARRAYVAR
  400.  TK_CONFIG_IMAGE</PRE>
  401. <DT><STRONG><A NAME="item_Types%3A">Types:</A></STRONG><BR>
  402. <DD>
  403. <PRE>
  404.  Var, Arg, LangCallback, LangFreeProc.</PRE>
  405. <DT><STRONG><A NAME="item_Functions_and_macros%3A">Functions and macros:</A></STRONG><BR>
  406. <DD>
  407. <PRE>
  408.  Lang_SplitList, LangString, LangSetString, LangSetDefault,
  409.  LangSetInt, LangSetDouble Tcl_ArgResult, LangCallbackArg,
  410.  LangSaveVar, LangFreeVar,
  411.  LangFreeSplitProc, LangFreeArg, Tcl_DoubleResults, Tcl_IntResults,
  412.  LangDoCallback, Tk_WidgetResult, Tcl_CreateCommand,
  413.  Tcl_DeleteCommand, Tcl_GetResult.</PRE>
  414. </DL>
  415. <P>Current implementation contains enough to make it possible to compile
  416. <CODE>mTk/tkText*.[ch]</CODE> with the virgin <STRONG>Tk</STRONG>.</P>
  417. <P>
  418. <H2><A NAME="new types of events ">New types of events ????</A></H2>
  419. <P>PortableTk defines following new types of events:</P>
  420. <PRE>
  421.  TK_EVENTTYPE_NONE
  422.  TK_EVENTTYPE_STRING
  423.  TK_EVENTTYPE_NUMBER
  424.  TK_EVENTTYPE_WINDOW
  425.  TK_EVENTTYPE_ATOM
  426.  TK_EVENTTYPE_DISPLAY
  427.  TK_EVENTTYPE_DATA</PRE>
  428. <P>and a function</P>
  429. <PRE>
  430.  char * Tk_EventInfo(int letter,
  431.             Tk_Window tkwin, XEvent *eventPtr,
  432.             KeySym keySym, int *numPtr, int *isNum, int *type,
  433.             int num_size, char *numStorage)</PRE>
  434. <P>
  435. <HR>
  436. <H1><A NAME="checking for trouble">Checking for trouble</A></H1>
  437. <P>If you start with working TCL code, you can start convertion using
  438. the above hints. Good indication that you are doing is OK is absence
  439. of <A HREF="#item_sprintf"><CODE>sprintf</CODE></A> and <CODE>sscanf</CODE> in your code (at least in the part that is
  440. working with interpreter).</P>
  441. <P>
  442. <HR>
  443. <H1><A NAME="additional api">Additional API</A></H1>
  444. <P>What is described here is not included into base <STRONG>portableTk</STRONG>
  445. distribution. Currently it is coded in <STRONG>TCL</STRONG> and as Perl macros (core
  446. is coded as functions, so theoretically you can use the same object
  447. files with different interpreted languages).</P>
  448. <P>
  449. <H2><A NAME="listfactory"><CODE>ListFactory</CODE></A></H2>
  450. <P>Dynamic arrays in <STRONG>TCL</STRONG> are used for two different purposes: to
  451. construct strings, and to construct lists. These two usages will have
  452. separate interfaces in other languages (since list is a different type
  453. from a string), so you should use a different interface in your code.</P>
  454. <P>The type for construction of dynamic lists is <CODE>ListFactory</CODE>. The API
  455. below is a counterpart of the API for construction of dynamic lists
  456. in <STRONG>TCL</STRONG>:</P>
  457. <PRE>
  458.  void ListFactoryInit(ListFactory *)
  459.  void ListFactoryFinish(ListFactory *)
  460.  void ListFactoryFree(ListFactory *)
  461.  Arg * ListFactoryArg(ListFactory *)
  462.  void ListFactoryAppend(ListFactory *, Arg *arg)
  463.  void ListFactoryAppendCopy(ListFactory *, Arg *arg)
  464.  ListFactory * ListFactoryNewLevel(ListFactory *)
  465.  ListFactory * ListFactoryEndLevel(ListFactory *)
  466.  void ListFactoryResult(Tcl_Interp *, ListFactory *)</PRE>
  467. <P>The difference is that a call to <CODE>ListFactoryFinish</CODE> should precede the
  468. actual usage of the value of <CODE>ListFactory</CODE>, and there are two
  469. different ways to append an <A HREF="#item_Arg"><CODE>Arg</CODE></A> to a <CODE>ListFactory</CODE>:
  470. <CODE>ListFactoryAppendCopy()</CODE> guarantees that the value of <CODE>arg</CODE> is copied
  471. to the list, but <CODE>ListFactoryAppend()</CODE> may append to the list a
  472. reference to the current value of <CODE>arg</CODE>. If you are not going to change
  473. the value of <CODE>arg</CODE> after appending, the call to ListFactoryAppend may
  474. be quicker.</P>
  475. <P>As in <STRONG>TCL</STRONG>, the call to <CODE>ListFactoryFree()</CODE> does not free the
  476. <CODE>ListFactory</CODE>, only the objects it references.</P>
  477. <P>The functions <CODE>ListFactoryNewLevel()</CODE> and <CODE>ListFactoryEndLevel()</CODE> return a
  478. pointer to a <CODE>ListFactory</CODE> to fill. The argument of
  479. <CODE>ListFactoryEndLevel()</CODE> cannot be used after a call to this function.</P>
  480. <P>
  481. <H2><A NAME="dstrings">DStrings</A></H2>
  482. <P>Production of strings are still supported in <STRONG>portableTk</STRONG>.</P>
  483. <P>
  484. <H2><A NAME="accessing args">Accessing <A HREF="#item_Arg"><CODE>Arg</CODE></A>s</A></H2>
  485. <P>The following functions for getting a value of an <A HREF="#item_Arg"><CODE>Arg</CODE></A> <EM>may</EM> be
  486. provided:</P>
  487. <PRE>
  488.  double LangDouble(Arg)
  489.  int LangInt(Arg)
  490.  long LangLong(Arg)
  491.  int LangIsList(Arg arg)</PRE>
  492. <P>The function <CODE>LangIsList()</CODE> is supported only partially under <STRONG>TCL</STRONG>,
  493. since there is no data types. It checks whether there is a space
  494. inside the string <CODE>arg</CODE>.</P>
  495. <P>
  496. <H2><A NAME="assigning numbers to args">Assigning numbers to <A HREF="#item_Arg"><CODE>Arg</CODE></A>s</A></H2>
  497. <P>While <CODE>LangSetDouble()</CODE> and <CODE>LangSetInt()</CODE> are supported ways to assign
  498. numbers to assign an integer value to a variable, for the sake of
  499. efficiency under <STRONG>TCL</STRONG> it is supposed that the destination of these
  500. commands was massaged before the call so it contains a long enough
  501. string to <A HREF="#item_sprintf"><CODE>sprintf()</CODE></A> the numbers inside it. If you are going to
  502. immediately use the resulting <A HREF="#item_Arg"><CODE>Arg</CODE></A>, the best way to do this is to
  503. declare a buffer in the beginning of a block by</P>
  504. <PRE>
  505.    dArgBuffer;</PRE>
  506. <P>and assign this buffer to the <A HREF="#item_Arg"><CODE>Arg</CODE></A> by</P>
  507. <PRE>
  508.    void LangSetDefaultBuffer(Arg *)</PRE>
  509. <P>You can also create the <CODE>buffer(s)</CODE> manually and assign them using</P>
  510. <PRE>
  511.    void LangSetBuffer(Arg *, char *)</PRE>
  512. <P>This is the only choice if you need to assign numeric values to
  513. several <A HREF="#item_Arg"><CODE>Arg</CODE></A>s simultaneously. The advantage of the first approach is
  514. that the above declarations can be made <CODE>nop</CODE>s in different languages.</P>
  515. <P>Note that if you apply <CODE>LangSetDefaultBuffer</CODE> to an <A HREF="#item_Arg"><CODE>Arg</CODE></A> that
  516. contains some value, you can create a leak if you do not free that
  517. <A HREF="#item_Arg"><CODE>Arg</CODE></A> first. This is a non-problem in real languages, but can be a
  518. trouble in <CODE>TCL</CODE>, unless you use only the above API.</P>
  519. <P>
  520. <H2><A NAME="creating new args">Creating new <A HREF="#item_Arg"><CODE>Arg</CODE></A>s</A></H2>
  521. <P>The API for creating a new <A HREF="#item_Arg"><CODE>Arg</CODE></A> is</P>
  522. <PRE>
  523.  void LangNewArg(Arg *, LangFreeProc *)</PRE>
  524. <P>The API for creating a new <A HREF="#item_Arg"><CODE>Arg</CODE></A> is absent. Just initialize <A HREF="#item_Arg"><CODE>Arg</CODE></A> to
  525. be <CODE>NULL</CODE>, and apply one of <CODE>LangSet...</CODE> methods.</P>
  526. <P>After you use this <A HREF="#item_Arg"><CODE>Arg</CODE></A>, it should be freed thusly:</P>
  527. <P><CODE>LangFreeArg(arg, freeProc)</CODE>.</P>
  528. <P>
  529. <H2><A NAME="evaluating a list">Evaluating a list</A></H2>
  530. <P>Use</P>
  531. <PRE>
  532.  int LangArgEval(Tcl_Interp *, Arg arg)</PRE>
  533. <P>Here <CODE>arg</CODE> should be a list to evaluate, in particular, the first
  534. element should be a <A HREF="#item_LangCallback"><CODE>LangCallback</CODE></A> massaged to be an <A HREF="#item_Arg"><CODE>Arg</CODE></A>. The
  535. arguments can be send to the subroutine by reference or by value in
  536. different languages.</P>
  537. <P>
  538. <H2><A NAME="getting result as arg">Getting result as <A HREF="#item_Arg"><CODE>Arg</CODE></A></A></H2>
  539. <P>Use <CODE>Tcl_ArgResult</CODE>. It is not guaranteed that result survives this
  540. operation, so the <A HREF="#item_Arg"><CODE>Arg</CODE></A> you get should be the only mean to access the
  541. data from this moment on. After you use this <A HREF="#item_Arg"><CODE>Arg</CODE></A>, you should free
  542. it with <CODE>freeProc</CODE> <CODE>LANG_DYNAMIC</CODE> (you can do LangSet...() in between).</P>
  543. <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
  544. <TR><TD CLASS=block VALIGN=MIDDLE WIDTH=100% BGCOLOR="#cccccc">
  545. <STRONG><P CLASS=block> Tk2portableTk - how to make your B<Tk> source portable to other
  546. interpreted languages.</P></STRONG>
  547. </TD></TR>
  548. </TABLE>
  549.  
  550. </BODY>
  551.  
  552. </HTML>
  553.