tcl_demo.pp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. {* tcl_demo.pas
  2. * ------------------------------------------------
  3. * Copyright 2002 by Bert Raccoon aka Max Artemev
  4. * ([email protected], [email protected])
  5. * ------------------------------------------------
  6. * Demo for tcl80.pas unit.
  7. * Creating the Tcl interpreter, executing file, registering
  8. * new commands, call a function defined in the script.
  9. *
  10. * Under Win32 can cause crash.
  11. *}
  12. program test;
  13. uses tcl80, SysUtils;
  14. {*
  15. * Function for testing that string is correct number
  16. *}
  17. function is_num(const src: PChar): Boolean;
  18. var
  19. i: integer;
  20. begin
  21. is_num:=True;
  22. i:=0;
  23. repeat
  24. is_num:=is_num and ((src + i)^ in ['0'..'9']);
  25. inc(i);
  26. until (src + i)^ = #0;
  27. end;
  28. function Test_max(clientData: Tcl_ClientData; {* Some user defined data. *}
  29. interp: PTcl_Interp; {* Pointer to Tcl interpreter *}
  30. argc: integer; {* Arguments counter, arguments, etc *}
  31. argv: Tcl_Argv): longint; {* Remeber! *NIX `integer` type is 16 bit! *}
  32. cdecl; {* C calling convention *}
  33. var
  34. arg : PChar;
  35. idx,
  36. value,
  37. maxVal : LongInt;
  38. begin
  39. maxVal := 0; {* Zero variable. Very stupid comment? ;)) *}
  40. {* The `max` can be done with at least two digits
  41. * In ArgvItem(argv,0) passed function name
  42. *}
  43. if (argc < 3) then
  44. begin
  45. Tcl_AppendResult(interp, ['bad # arg: ', ArgvItem(argv,0), ' num1 num2 [..numN]', nil]);
  46. {* Under Win32 calling of this function can cause crash *}
  47. Test_max:=TCL_ERROR; {* Error was occured *}
  48. exit; {* Leave *}
  49. end;
  50. for idx := 1 to argc-1 do {* In argv[0] passed function name, so
  51. * go from the first index, not zero.
  52. *}
  53. begin
  54. arg := ArgvItem(argv,idx); {* get an argument *}
  55. if (not is_num(arg)) then {* Is right number? *}
  56. begin
  57. Tcl_AppendResult(interp,[' "', arg, '" is not a valid integer value']);
  58. Test_max:=TCL_ERROR; {* Error was occured *}
  59. exit; {* leave *}
  60. end;
  61. Value:=StrToInt(arg); {* Convert PChar->Integer *}
  62. if (value > maxVal) then
  63. maxVal := value; {* Calculate maximum number *}
  64. end;
  65. {* Set the result for the our function.
  66. * result type always is PChar
  67. *}
  68. Tcl_SetResult(interp, PChar(IntToStr(maxVal)), nil);
  69. {* exit successful *}
  70. Test_max:=TCL_OK;
  71. end;
  72. {*
  73. * Old and good known Pascal procedure :)
  74. *}
  75. function Test_writeln(clientData: Tcl_ClientData; interp: pTcl_Interp; argc: integer; argv: Tcl_Argv): longint; cdecl;
  76. var
  77. i: integer;
  78. Buff: string;
  79. begin
  80. Buff := '';
  81. for i:=1 to argc-1 do
  82. Buff:=Buff + ArgvItem(argv,i); {* work around some bugs *}
  83. writeln(Buff);
  84. Test_writeln:=TCL_OK;
  85. end;
  86. var
  87. interp: PTcl_Interp;
  88. code: integer;
  89. begin
  90. interp := Tcl_CreateInterp(); {* Create an interpreter *}
  91. Tcl_Init(interp); {* Initialize *}
  92. {* Register/override in the Tcl engine our new functions *}
  93. Tcl_CreateCommand(interp,'max', TTclCmdProc(@Test_max),nil,nil);
  94. Tcl_CreateCommand(interp,'writeln',TTclCmdProc(@Test_writeln),nil,nil);
  95. code := Tcl_EvalFile(interp,'test.tcl'); {* Execute script *}
  96. if (code <> TCL_OK) then {* Is all okay? *}
  97. writeln(Tcl_GetStringResult(interp));
  98. {* Call a function `foo` defined in the script *}
  99. code := Tcl_VarEval(interp,['foo ','1 2 3',nil]);
  100. if (code <> TCL_OK) then
  101. writeln(Tcl_GetStringResult(interp));
  102. Tcl_DeleteInterp(interp); {* Release interpreter *}
  103. end.