PageRenderTime 71ms CodeModel.GetById 7ms RepoModel.GetById 0ms app.codeStats 0ms

/TCL/src/commands/LappendCmd.cs

https://bitbucket.org/eumario/csharp-sqlite
C# | 159 lines | 90 code | 21 blank | 48 comment | 16 complexity | 93a33587c82d0fa201bd430c0a6794a5 MD5 | raw file
  1. /*
  2. * LappendCmd.java
  3. *
  4. * Copyright (c) 1997 Cornell University.
  5. * Copyright (c) 1997 Sun Microsystems, Inc.
  6. * Copyright (c) 1998-1999 by Scriptics Corporation.
  7. * Copyright (c) 1999 Mo DeJong.
  8. *
  9. * See the file "license.terms" for information on usage and
  10. * redistribution of this file, and for a DISCLAIMER OF ALL
  11. * WARRANTIES.
  12. *
  13. * Included in SQLite3 port to C# for use in testharness only; 2008 Noah B Hart
  14. *
  15. * RCS @(#) $Id: LappendCmd.java,v 1.3 2003/01/09 02:15:39 mdejong Exp $
  16. *
  17. */
  18. using System;
  19. namespace tcl.lang
  20. {
  21. /// <summary> This class implements the built-in "lappend" command in Tcl.</summary>
  22. class LappendCmd : Command
  23. {
  24. /// <summary>
  25. /// Tcl_LappendObjCmd -> LappendCmd.cmdProc
  26. ///
  27. /// This procedure is invoked to process the "lappend" Tcl command.
  28. /// See the user documentation for details on what it does.
  29. /// </summary>
  30. public TCL.CompletionCode cmdProc( Interp interp, TclObject[] objv )
  31. {
  32. TclObject varValue, newValue = null;
  33. int i;//int numElems, i, j;
  34. bool createdNewObj, createVar;
  35. if ( objv.Length < 2 )
  36. {
  37. throw new TclNumArgsException( interp, 1, objv, "varName ?value value ...?" );
  38. }
  39. if ( objv.Length == 2 )
  40. {
  41. try
  42. {
  43. newValue = interp.getVar( objv[1], 0 );
  44. }
  45. catch ( TclException e )
  46. {
  47. // The variable doesn't exist yet. Just create it with an empty
  48. // initial value.
  49. varValue = TclList.newInstance();
  50. try
  51. {
  52. newValue = interp.setVar( objv[1], varValue, 0 );
  53. }
  54. finally
  55. {
  56. if ( newValue == null )
  57. varValue.release(); // free unneeded object
  58. }
  59. interp.resetResult();
  60. return TCL.CompletionCode.RETURN;
  61. }
  62. }
  63. else
  64. {
  65. // We have arguments to append. We used to call Tcl_SetVar2 to
  66. // append each argument one at a time to ensure that traces were run
  67. // for each append step. We now append the arguments all at once
  68. // because it's faster. Note that a read trace and a write trace for
  69. // the variable will now each only be called once. Also, if the
  70. // variable's old value is unshared we modify it directly, otherwise
  71. // we create a new copy to modify: this is "copy on write".
  72. createdNewObj = false;
  73. createVar = true;
  74. try
  75. {
  76. varValue = interp.getVar( objv[1], 0 );
  77. }
  78. catch ( TclException e )
  79. {
  80. // We couldn't read the old value: either the var doesn't yet
  81. // exist or it's an array element. If it's new, we will try to
  82. // create it with Tcl_ObjSetVar2 below.
  83. // FIXME : not sure we even need this parse for anything!
  84. // If we do not need to parse could we at least speed it up a bit
  85. string varName;
  86. int nameBytes;
  87. varName = objv[1].ToString();
  88. nameBytes = varName.Length; // Number of Unicode chars in string
  89. for ( i = 0; i < nameBytes; i++ )
  90. {
  91. if ( varName[i] == '(' )
  92. {
  93. i = nameBytes - 1;
  94. if ( varName[i] == ')' )
  95. {
  96. // last char is ')' => array ref
  97. createVar = false;
  98. }
  99. break;
  100. }
  101. }
  102. varValue = TclList.newInstance();
  103. createdNewObj = true;
  104. }
  105. // We only take this branch when the catch branch was not run
  106. if ( createdNewObj == false && varValue.Shared )
  107. {
  108. varValue = varValue.duplicate();
  109. createdNewObj = true;
  110. }
  111. // Insert the new elements at the end of the list.
  112. for ( i = 2; i < objv.Length; i++ )
  113. TclList.append( interp, varValue, objv[i] );
  114. // No need to call varValue.invalidateStringRep() since it
  115. // is called during the TclList.append operation.
  116. // Now store the list object back into the variable. If there is an
  117. // error setting the new value, decrement its ref count if it
  118. // was new and we didn't create the variable.
  119. try
  120. {
  121. newValue = interp.setVar( objv[1].ToString(), varValue, 0 );
  122. }
  123. catch ( TclException e )
  124. {
  125. if ( createdNewObj && !createVar )
  126. {
  127. varValue.release(); // free unneeded obj
  128. }
  129. throw;
  130. }
  131. }
  132. // Set the interpreter's object result to refer to the variable's value
  133. // object.
  134. interp.setResult( newValue );
  135. return TCL.CompletionCode.RETURN;
  136. }
  137. }
  138. }