Exemplo n.º 1
0
        internal static string pkgPresent(Interp interp, string pkgName, string version, bool exact)
        {
            Package pkg;
            VersionSatisfiesResult vsres = new VersionSatisfiesResult();
            int result;

            pkg = (Package)interp.packageTable[pkgName];
            if (pkg != null)
            {
                if ((System.Object)pkg.version != null)
                {
                    // At this point we know that the package is present.  Make sure
                    // that the provided version meets the current requirement.

                    if ((System.Object)version == null)
                    {
                        return(pkg.version);
                    }
                    result = compareVersions(pkg.version, version, vsres);
                    if ((vsres.satisfies && !exact) || (result == 0))
                    {
                        return(pkg.version);
                    }
                    throw new TclException(interp, "version conflict for package \"" + pkgName + "\": have " + pkg.version + ", need " + version);
                }
            }

            if ((System.Object)version != null)
            {
                throw new TclException(interp, "package " + pkgName + " " + version + " is not present");
            }
            else
            {
                throw new TclException(interp, "package " + pkgName + " is not present");
            }
        }
Exemplo n.º 2
0
        private static int compareVersions(string v1, string v2, VersionSatisfiesResult vsres)
        {
            int  i;
            int  max;
            int  n1          = 0;
            int  n2          = 0;
            bool thisIsMajor = true;

            string[] v1ns;
            string[] v2ns;

            // Each iteration of the following loop processes one number from
            // each string, terminated by a ".".  If those numbers don't match
            // then the comparison is over;  otherwise, we loop back for the
            // next number.


            // This should never happen because null strings would not
            // have gotten past the version verify.

            if (((System.Object)v1 == null) || ((System.Object)v2 == null))
            {
                throw new TclRuntimeError("null version in package version compare");
            }
            v1ns = split(v1, '.');
            v2ns = split(v2, '.');

            // We are sure there is at least one string in each array so
            // this should never happen.

            if (v1ns.Length == 0 || v2ns.Length == 0)
            {
                throw new TclRuntimeError("version length is 0");
            }
            if (v1ns.Length > v2ns.Length)
            {
                max = v1ns.Length;
            }
            else
            {
                max = v2ns.Length;
            }

            for (i = 0; i < max; i++)
            {
                n1 = n2 = 0;

                // Grab number from each version ident if version spec
                // ends the use a 0 as value.

                try
                {
                    if (i < v1ns.Length)
                    {
                        n1 = System.Int32.Parse(v1ns[i]);
                    }
                    if (i < v2ns.Length)
                    {
                        n2 = System.Int32.Parse(v2ns[i]);
                    }
                }
                catch (System.FormatException ex)
                {
                    throw new TclRuntimeError("NumberFormatException for package versions \"" + v1 + "\" or \"" + v2 + "\"");
                }

                // Compare and go on to the next version number if the
                // current numbers match.

                if (n1 != n2)
                {
                    break;
                }
                thisIsMajor = false;
            }
            if (vsres != null)
            {
                vsres.satisfies = ((n1 == n2) || ((n1 > n2) && !thisIsMajor));
            }
            if (n1 > n2)
            {
                return(1);
            }
            else if (n1 == n2)
            {
                return(0);
            }
            else
            {
                return(-1);
            }
        }
Exemplo n.º 3
0
        internal static string pkgRequire(Interp interp, string pkgName, string version, bool exact)
        {
            VersionSatisfiesResult vsres;
            Package  pkg;
            PkgAvail avail, best;
            string   script;

            System.Text.StringBuilder sbuf;
            int pass, result;

            // Do extra check to make sure that version is not
            // null when the exact flag is set to true.

            if ((System.Object)version == null && exact)
            {
                throw new TclException(interp, "conflicting arguments : version == null and exact == true");
            }

            // Before we can compare versions the version string
            // must be verified but if it is null we are just looking
            // for the latest version so skip the check in this case.

            if ((System.Object)version != null)
            {
                checkVersion(interp, version);
            }

            // It can take up to three passes to find the package:  one pass to
            // run the "package unknown" script, one to run the "package ifneeded"
            // script for a specific version, and a final pass to lookup the
            // package loaded by the "package ifneeded" script.

            vsres = new VersionSatisfiesResult();
            for (pass = 1; ; pass++)
            {
                pkg = findPackage(interp, pkgName);
                if ((System.Object)pkg.version != null)
                {
                    break;
                }

                // The package isn't yet present.  Search the list of available
                // versions and invoke the script for the best available version.

                best = null;
                for (avail = pkg.avail; avail != null; avail = avail.next)
                {
                    if ((best != null) && (compareVersions(avail.version, best.version, null) <= 0))
                    {
                        continue;
                    }
                    if ((System.Object)version != null)
                    {
                        result = compareVersions(avail.version, version, vsres);
                        if ((result != 0) && exact)
                        {
                            continue;
                        }
                        if (!vsres.satisfies)
                        {
                            continue;
                        }
                    }
                    best = avail;
                }
                if (best != null)
                {
                    // We found an ifneeded script for the package.  Be careful while
                    // executing it:  this could cause reentrancy, so (a) protect the
                    // script itself from deletion and (b) don't assume that best
                    // will still exist when the script completes.

                    script = best.script;
                    try
                    {
                        interp.eval(script, TCL.EVAL_GLOBAL);
                    }
                    catch (TclException e)
                    {
                        interp.addErrorInfo("\n    (\"package ifneeded\" script)");

                        // Throw the error with new info added to errorInfo.

                        throw;
                    }
                    interp.resetResult();
                    pkg = findPackage(interp, pkgName);
                    break;
                }

                // Package not in the database.  If there is a "package unknown"
                // command, invoke it (but only on the first pass;  after that,
                // we should not get here in the first place).

                if (pass > 1)
                {
                    break;
                }
                script = interp.packageUnknown;
                if ((System.Object)script != null)
                {
                    sbuf = new System.Text.StringBuilder();
                    try
                    {
                        Util.appendElement(interp, sbuf, script);
                        Util.appendElement(interp, sbuf, pkgName);
                        if ((System.Object)version == null)
                        {
                            Util.appendElement(interp, sbuf, "");
                        }
                        else
                        {
                            Util.appendElement(interp, sbuf, version);
                        }
                        if (exact)
                        {
                            Util.appendElement(interp, sbuf, "-exact");
                        }
                    }
                    catch (TclException e)
                    {
                        throw new TclRuntimeError("unexpected TclException: " + e.Message);
                    }
                    try
                    {
                        interp.eval(sbuf.ToString(), TCL.EVAL_GLOBAL);
                    }
                    catch (TclException e)
                    {
                        interp.addErrorInfo("\n    (\"package unknown\" script)");

                        // Throw the first exception.

                        throw;
                    }
                    interp.resetResult();
                }
            }
            if ((System.Object)pkg.version == null)
            {
                sbuf = new System.Text.StringBuilder();
                sbuf.Append("can't find package " + pkgName);
                if ((System.Object)version != null)
                {
                    sbuf.Append(" " + version);
                }
                throw new TclException(interp, sbuf.ToString());
            }

            // At this point we know that the package is present.  Make sure that the
            // provided version meets the current requirement.

            if ((System.Object)version == null)
            {
                return(pkg.version);
            }

            result = compareVersions(pkg.version, version, vsres);
            if ((vsres.satisfies && !exact) || (result == 0))
            {
                return(pkg.version);
            }

            // If we have a version conflict we throw a TclException.

            throw new TclException(interp, "version conflict for package \"" + pkgName + "\": have " + pkg.version + ", need " + version);
        }
Exemplo n.º 4
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] objv)
        {
            VersionSatisfiesResult vsres;
            Package  pkg;
            PkgAvail avail;
            PkgAvail prev;
            string   version;
            string   pkgName;
            string   key;
            string   cmd;
            string   ver1, ver2;

            System.Text.StringBuilder sbuf;
            IDictionaryEnumerator     enum_Renamed;
            int  i, opt, exact;
            bool once;

            if (objv.Length < 2)
            {
                throw new TclNumArgsException(interp, 1, objv, "option ?arg arg ...?");
            }
            opt = TclIndex.get(interp, objv[1], validCmds, "option", 0);
            switch (opt)
            {
            case OPT_FORGET:  {
                // Forget takes 0 or more arguments.

                for (i = 2; i < objv.Length; i++)
                {
                    // We do not need to check to make sure
                    // package name is "" because it would not
                    // be in the hash table so name will be ignored.


                    pkgName = objv[i].ToString();
                    pkg     = (Package)interp.packageTable[pkgName];

                    // If this package does not exist, go to next one.

                    if (pkg == null)
                    {
                        continue;
                    }
                    SupportClass.HashtableRemove(interp.packageTable, pkgName);
                    while (pkg.avail != null)
                    {
                        avail     = pkg.avail;
                        pkg.avail = avail.next;
                        avail     = null;
                    }
                    pkg = null;
                }
                return(TCL.CompletionCode.RETURN);
            }

            case OPT_IFNEEDED:  {
                if ((objv.Length < 4) || (objv.Length > 5))
                {
                    throw new TclNumArgsException(interp, 1, objv, "ifneeded package version ?script?");
                }
                pkgName = objv[2].ToString();
                version = objv[3].ToString();

                // Verify that this version string is valid.

                checkVersion(interp, version);
                if (objv.Length == 4)
                {
                    pkg = (Package)interp.packageTable[pkgName];
                    if (pkg == null)
                    {
                        return(TCL.CompletionCode.RETURN);
                    }
                }
                else
                {
                    pkg = findPackage(interp, pkgName);
                }
                for (avail = pkg.avail, prev = null; avail != null; prev = avail, avail = avail.next)
                {
                    if (compareVersions(avail.version, version, null) == 0)
                    {
                        if (objv.Length == 4)
                        {
                            // If doing a query return current script.

                            interp.setResult(avail.script);
                            return(TCL.CompletionCode.RETURN);
                        }

                        // We matched so we must be setting the script.

                        break;
                    }
                }

                // When we do not match on a query return nothing.

                if (objv.Length == 4)
                {
                    return(TCL.CompletionCode.RETURN);
                }
                if (avail == null)
                {
                    avail         = new PkgAvail();
                    avail.version = version;
                    if (prev == null)
                    {
                        avail.next = pkg.avail;
                        pkg.avail  = avail;
                    }
                    else
                    {
                        avail.next = prev.next;
                        prev.next  = avail;
                    }
                }

                avail.script = objv[4].ToString();
                return(TCL.CompletionCode.RETURN);
            }

            case OPT_NAMES:  {
                if (objv.Length != 2)
                {
                    throw new TclNumArgsException(interp, 1, objv, "names");
                }

                try
                {
                    sbuf         = new System.Text.StringBuilder();
                    enum_Renamed = interp.packageTable.GetEnumerator();
                    once         = false;
                    while (enum_Renamed.MoveNext())
                    {
                        once = true;
                        key  = ((string)enum_Renamed.Current);
                        pkg  = (Package)enum_Renamed.Value;
                        if (((System.Object)pkg.version != null) || (pkg.avail != null))
                        {
                            Util.appendElement(interp, sbuf, key);
                        }
                    }
                    if (once)
                    {
                        interp.setResult(sbuf.ToString());
                    }
                }
                catch (TclException e)
                {
                    throw new TclRuntimeError("unexpected TclException: " + e);
                }
                return(TCL.CompletionCode.RETURN);
            }

            case OPT_PRESENT:  {
                if (objv.Length < 3)
                {
                    throw new TclNumArgsException(interp, 2, objv, "?-exact? package ?version?");
                }

                if (objv[2].ToString().Equals("-exact"))
                {
                    exact = 1;
                }
                else
                {
                    exact = 0;
                }

                version = null;
                if (objv.Length == (4 + exact))
                {
                    version = objv[3 + exact].ToString();
                    checkVersion(interp, version);
                }
                else if ((objv.Length != 3) || (exact == 1))
                {
                    throw new TclNumArgsException(interp, 2, objv, "?-exact? package ?version?");
                }
                if (exact == 1)
                {
                    version = pkgPresent(interp, objv[3].ToString(), version, true);
                }
                else
                {
                    version = pkgPresent(interp, objv[2].ToString(), version, false);
                }
                interp.setResult(version);
                break;
            }

            case OPT_PROVIDE:  {
                if ((objv.Length < 3) || (objv.Length > 4))
                {
                    throw new TclNumArgsException(interp, 1, objv, "provide package ?version?");
                }
                if (objv.Length == 3)
                {
                    pkg = (Package)interp.packageTable[objv[2].ToString()];
                    if (pkg != null)
                    {
                        if ((System.Object)pkg.version != null)
                        {
                            interp.setResult(pkg.version);
                        }
                    }
                    return(TCL.CompletionCode.RETURN);
                }

                pkgProvide(interp, objv[2].ToString(), objv[3].ToString());
                return(TCL.CompletionCode.RETURN);
            }

            case OPT_REQUIRE:  {
                if ((objv.Length < 3) || (objv.Length > 5))
                {
                    throw new TclNumArgsException(interp, 1, objv, "require ?-exact? package ?version?");
                }

                if (objv[2].ToString().Equals("-exact"))
                {
                    exact = 1;
                }
                else
                {
                    exact = 0;
                }
                version = null;
                if (objv.Length == (4 + exact))
                {
                    version = objv[3 + exact].ToString();
                    checkVersion(interp, version);
                }
                else if ((objv.Length != 3) || (exact == 1))
                {
                    throw new TclNumArgsException(interp, 1, objv, "require ?-exact? package ?version?");
                }
                if (exact == 1)
                {
                    version = pkgRequire(interp, objv[3].ToString(), version, true);
                }
                else
                {
                    version = pkgRequire(interp, objv[2].ToString(), version, false);
                }
                interp.setResult(version);
                return(TCL.CompletionCode.RETURN);
            }

            case OPT_UNKNOWN:  {
                if (objv.Length > 3)
                {
                    throw new TclNumArgsException(interp, 1, objv, "unknown ?command?");
                }
                if (objv.Length == 2)
                {
                    if ((System.Object)interp.packageUnknown != null)
                    {
                        interp.setResult(interp.packageUnknown);
                    }
                }
                else if (objv.Length == 3)
                {
                    interp.packageUnknown = null;

                    cmd = objv[2].ToString();
                    if (cmd.Length > 0)
                    {
                        interp.packageUnknown = cmd;
                    }
                }
                return(TCL.CompletionCode.RETURN);
            }

            case OPT_VCOMPARE:  {
                if (objv.Length != 4)
                {
                    throw new TclNumArgsException(interp, 1, objv, "vcompare version1 version2");
                }

                ver1 = objv[2].ToString();

                ver2 = objv[3].ToString();
                checkVersion(interp, ver1);
                checkVersion(interp, ver2);
                interp.setResult(compareVersions(ver1, ver2, null));
                return(TCL.CompletionCode.RETURN);
            }

            case OPT_VERSIONS:  {
                if (objv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 1, objv, "versions package");
                }

                pkg = (Package)interp.packageTable[objv[2].ToString()];
                if (pkg != null)
                {
                    try
                    {
                        sbuf = new System.Text.StringBuilder();
                        once = false;
                        for (avail = pkg.avail; avail != null; avail = avail.next)
                        {
                            once = true;
                            Util.appendElement(interp, sbuf, avail.version);
                        }
                        if (once)
                        {
                            interp.setResult(sbuf.ToString());
                        }
                    }
                    catch (TclException e)
                    {
                        throw new TclRuntimeError("unexpected TclException: " + e.Message, e);
                    }
                }
                return(TCL.CompletionCode.RETURN);
            }

            case OPT_VSATISFIES:  {
                if (objv.Length != 4)
                {
                    throw new TclNumArgsException(interp, 1, objv, "vsatisfies version1 version2");
                }


                ver1 = objv[2].ToString();

                ver2 = objv[3].ToString();
                checkVersion(interp, ver1);
                checkVersion(interp, ver2);
                vsres = new VersionSatisfiesResult();
                compareVersions(ver1, ver2, vsres);
                interp.setResult(vsres.satisfies);
                return(TCL.CompletionCode.RETURN);
            }

            default:  {
                throw new TclRuntimeError("TclIndex.get() error");
            }
            }             // end switch(opt)
            return(TCL.CompletionCode.RETURN);
        }
Exemplo n.º 5
0
    private static int compareVersions( string v1, string v2, VersionSatisfiesResult vsres )
    {
      int i;
      int max;
      int n1 = 0;
      int n2 = 0;
      bool thisIsMajor = true;
      string[] v1ns;
      string[] v2ns;

      // Each iteration of the following loop processes one number from
      // each string, terminated by a ".".  If those numbers don't match
      // then the comparison is over;  otherwise, we loop back for the
      // next number.


      // This should never happen because null strings would not
      // have gotten past the version verify.

      if ( ( (System.Object)v1 == null ) || ( (System.Object)v2 == null ) )
      {
        throw new TclRuntimeError( "null version in package version compare" );
      }
      v1ns = split( v1, '.' );
      v2ns = split( v2, '.' );

      // We are sure there is at least one string in each array so 
      // this should never happen.

      if ( v1ns.Length == 0 || v2ns.Length == 0 )
      {
        throw new TclRuntimeError( "version length is 0" );
      }
      if ( v1ns.Length > v2ns.Length )
      {
        max = v1ns.Length;
      }
      else
      {
        max = v2ns.Length;
      }

      for ( i = 0; i < max; i++ )
      {
        n1 = n2 = 0;

        // Grab number from each version ident if version spec
        // ends the use a 0 as value.

        try
        {
          if ( i < v1ns.Length )
          {
            n1 = System.Int32.Parse( v1ns[i] );
          }
          if ( i < v2ns.Length )
          {
            n2 = System.Int32.Parse( v2ns[i] );
          }
        }
        catch ( System.FormatException ex )
        {
          throw new TclRuntimeError( "NumberFormatException for package versions \"" + v1 + "\" or \"" + v2 + "\"" );
        }

        // Compare and go on to the next version number if the
        // current numbers match.

        if ( n1 != n2 )
        {
          break;
        }
        thisIsMajor = false;
      }
      if ( vsres != null )
      {
        vsres.satisfies = ( ( n1 == n2 ) || ( ( n1 > n2 ) && !thisIsMajor ) );
      }
      if ( n1 > n2 )
      {
        return 1;
      }
      else if ( n1 == n2 )
      {
        return 0;
      }
      else
      {
        return -1;
      }
    }
Exemplo n.º 6
0
    internal static string pkgRequire( Interp interp, string pkgName, string version, bool exact )
    {
      VersionSatisfiesResult vsres;
      Package pkg;
      PkgAvail avail, best;
      string script;
      StringBuilder sbuf;
      int pass, result;

      // Do extra check to make sure that version is not
      // null when the exact flag is set to true.

      if ( (System.Object)version == null && exact )
      {
        throw new TclException( interp, "conflicting arguments : version == null and exact == true" );
      }

      // Before we can compare versions the version string
      // must be verified but if it is null we are just looking
      // for the latest version so skip the check in this case.

      if ( (System.Object)version != null )
      {
        checkVersion( interp, version );
      }

      // It can take up to three passes to find the package:  one pass to
      // run the "package unknown" script, one to run the "package ifneeded"
      // script for a specific version, and a final pass to lookup the
      // package loaded by the "package ifneeded" script.

      vsres = new VersionSatisfiesResult();
      for ( pass = 1; ; pass++ )
      {
        pkg = findPackage( interp, pkgName );
        if ( (System.Object)pkg.version != null )
        {
          break;
        }

        // The package isn't yet present.  Search the list of available
        // versions and invoke the script for the best available version.

        best = null;
        for ( avail = pkg.avail; avail != null; avail = avail.next )
        {
          if ( ( best != null ) && ( compareVersions( avail.version, best.version, null ) <= 0 ) )
          {
            continue;
          }
          if ( (System.Object)version != null )
          {
            result = compareVersions( avail.version, version, vsres );
            if ( ( result != 0 ) && exact )
            {
              continue;
            }
            if ( !vsres.satisfies )
            {
              continue;
            }
          }
          best = avail;
        }
        if ( best != null )
        {
          // We found an ifneeded script for the package.  Be careful while
          // executing it:  this could cause reentrancy, so (a) protect the
          // script itself from deletion and (b) don't assume that best
          // will still exist when the script completes.

          script = best.script;
          try
          {
            interp.eval( script, TCL.EVAL_GLOBAL );
          }
          catch ( TclException e )
          {
            interp.addErrorInfo( "\n    (\"package ifneeded\" script)" );

            // Throw the error with new info added to errorInfo.

            throw;
          }
          interp.resetResult();
          pkg = findPackage( interp, pkgName );
          break;
        }

        // Package not in the database.  If there is a "package unknown"
        // command, invoke it (but only on the first pass;  after that,
        // we should not get here in the first place).

        if ( pass > 1 )
        {
          break;
        }
        script = interp.packageUnknown;
        if ( (System.Object)script != null )
        {
          sbuf = new StringBuilder();
          try
          {
            Util.appendElement( interp, sbuf, script );
            Util.appendElement( interp, sbuf, pkgName );
            if ( (System.Object)version == null )
            {
              Util.appendElement( interp, sbuf, "" );
            }
            else
            {
              Util.appendElement( interp, sbuf, version );
            }
            if ( exact )
            {
              Util.appendElement( interp, sbuf, "-exact" );
            }
          }
          catch ( TclException e )
          {
            throw new TclRuntimeError( "unexpected TclException: " + e.Message );
          }
          try
          {
            interp.eval( sbuf.ToString(), TCL.EVAL_GLOBAL );
          }
          catch ( TclException e )
          {
            interp.addErrorInfo( "\n    (\"package unknown\" script)" );

            // Throw the first exception.

            throw;
          }
          interp.resetResult();
        }
      }
      if ( (System.Object)pkg.version == null )
      {
        sbuf = new StringBuilder();
        sbuf.Append( "can't find package " + pkgName );
        if ( (System.Object)version != null )
        {
          sbuf.Append( " " + version );
        }
        throw new TclException( interp, sbuf.ToString() );
      }

      // At this point we know that the package is present.  Make sure that the
      // provided version meets the current requirement.

      if ( (System.Object)version == null )
      {
        return pkg.version;
      }

      result = compareVersions( pkg.version, version, vsres );
      if ( ( vsres.satisfies && !exact ) || ( result == 0 ) )
      {
        return pkg.version;
      }

      // If we have a version conflict we throw a TclException.

      throw new TclException( interp, "version conflict for package \"" + pkgName + "\": have " + pkg.version + ", need " + version );
    }
Exemplo n.º 7
0
    public TCL.CompletionCode cmdProc( Interp interp, TclObject[] objv )
    {
      VersionSatisfiesResult vsres;
      Package pkg;
      PkgAvail avail;
      PkgAvail prev;
      string version;
      string pkgName;
      string key;
      string cmd;
      string ver1, ver2;
      StringBuilder sbuf;
      IDictionaryEnumerator enum_Renamed;
      int i, opt, exact;
      bool once;

      if ( objv.Length < 2 )
      {
        throw new TclNumArgsException( interp, 1, objv, "option ?arg arg ...?" );
      }
      opt = TclIndex.get( interp, objv[1], validCmds, "option", 0 );
      switch ( opt )
      {

        case OPT_FORGET:
          {
            // Forget takes 0 or more arguments.

            for ( i = 2; i < objv.Length; i++ )
            {
              // We do not need to check to make sure
              // package name is "" because it would not
              // be in the hash table so name will be ignored.


              pkgName = objv[i].ToString();
              pkg = (Package)interp.packageTable[pkgName];

              // If this package does not exist, go to next one.

              if ( pkg == null )
              {
                continue;
              }
              SupportClass.HashtableRemove( interp.packageTable, pkgName );
              while ( pkg.avail != null )
              {
                avail = pkg.avail;
                pkg.avail = avail.next;
                avail = null;
              }
              pkg = null;
            }
            return TCL.CompletionCode.RETURN;
          }

        case OPT_IFNEEDED:
          {
            if ( ( objv.Length < 4 ) || ( objv.Length > 5 ) )
            {
              throw new TclNumArgsException( interp, 1, objv, "ifneeded package version ?script?" );
            }
            pkgName = objv[2].ToString();
            version = objv[3].ToString();

            // Verify that this version string is valid.

            checkVersion( interp, version );
            if ( objv.Length == 4 )
            {
              pkg = (Package)interp.packageTable[pkgName];
              if ( pkg == null )
                return TCL.CompletionCode.RETURN;
            }
            else
            {
              pkg = findPackage( interp, pkgName );
            }
            for ( avail = pkg.avail, prev = null; avail != null; prev = avail, avail = avail.next )
            {
              if ( compareVersions( avail.version, version, null ) == 0 )
              {
                if ( objv.Length == 4 )
                {
                  // If doing a query return current script.

                  interp.setResult( avail.script );
                  return TCL.CompletionCode.RETURN;
                }

                // We matched so we must be setting the script.

                break;
              }
            }

            // When we do not match on a query return nothing.

            if ( objv.Length == 4 )
            {
              return TCL.CompletionCode.RETURN;
            }
            if ( avail == null )
            {
              avail = new PkgAvail();
              avail.version = version;
              if ( prev == null )
              {
                avail.next = pkg.avail;
                pkg.avail = avail;
              }
              else
              {
                avail.next = prev.next;
                prev.next = avail;
              }
            }

            avail.script = objv[4].ToString();
            return TCL.CompletionCode.RETURN;
          }

        case OPT_NAMES:
          {
            if ( objv.Length != 2 )
            {
              throw new TclNumArgsException( interp, 1, objv, "names" );
            }

            try
            {
              sbuf = new StringBuilder();
              enum_Renamed = interp.packageTable.GetEnumerator();
              once = false;
              while ( enum_Renamed.MoveNext() )
              {
                once = true;
                key = ( (string)enum_Renamed.Current );
                pkg = (Package)enum_Renamed.Value;
                if ( ( (System.Object)pkg.version != null ) || ( pkg.avail != null ) )
                {
                  Util.appendElement( interp, sbuf, key );
                }
              }
              if ( once )
              {
                interp.setResult( sbuf.ToString() );
              }
            }
            catch ( TclException e )
            {

              throw new TclRuntimeError( "unexpected TclException: " + e );
            }
            return TCL.CompletionCode.RETURN;
          }

        case OPT_PRESENT:
          {
            if ( objv.Length < 3 )
            {
              throw new TclNumArgsException( interp, 2, objv, "?-exact? package ?version?" );
            }

            if ( objv[2].ToString().Equals( "-exact" ) )
            {
              exact = 1;
            }
            else
            {
              exact = 0;
            }

            version = null;
            if ( objv.Length == ( 4 + exact ) )
            {

              version = objv[3 + exact].ToString();
              checkVersion( interp, version );
            }
            else if ( ( objv.Length != 3 ) || ( exact == 1 ) )
            {
              throw new TclNumArgsException( interp, 2, objv, "?-exact? package ?version?" );
            }
            if ( exact == 1 )
            {

              version = pkgPresent( interp, objv[3].ToString(), version, true );
            }
            else
            {

              version = pkgPresent( interp, objv[2].ToString(), version, false );
            }
            interp.setResult( version );
            break;
          }

        case OPT_PROVIDE:
          {
            if ( ( objv.Length < 3 ) || ( objv.Length > 4 ) )
            {
              throw new TclNumArgsException( interp, 1, objv, "provide package ?version?" );
            }
            if ( objv.Length == 3 )
            {

              pkg = (Package)interp.packageTable[objv[2].ToString()];
              if ( pkg != null )
              {
                if ( (System.Object)pkg.version != null )
                {
                  interp.setResult( pkg.version );
                }
              }
              return TCL.CompletionCode.RETURN;
            }

            pkgProvide( interp, objv[2].ToString(), objv[3].ToString() );
            return TCL.CompletionCode.RETURN;
          }

        case OPT_REQUIRE:
          {
            if ( ( objv.Length < 3 ) || ( objv.Length > 5 ) )
            {
              throw new TclNumArgsException( interp, 1, objv, "require ?-exact? package ?version?" );
            }

            if ( objv[2].ToString().Equals( "-exact" ) )
            {
              exact = 1;
            }
            else
            {
              exact = 0;
            }
            version = null;
            if ( objv.Length == ( 4 + exact ) )
            {

              version = objv[3 + exact].ToString();
              checkVersion( interp, version );
            }
            else if ( ( objv.Length != 3 ) || ( exact == 1 ) )
            {
              throw new TclNumArgsException( interp, 1, objv, "require ?-exact? package ?version?" );
            }
            if ( exact == 1 )
            {

              version = pkgRequire( interp, objv[3].ToString(), version, true );
            }
            else
            {

              version = pkgRequire( interp, objv[2].ToString(), version, false );
            }
            interp.setResult( version );
            return TCL.CompletionCode.RETURN;
          }

        case OPT_UNKNOWN:
          {
            if ( objv.Length > 3 )
            {
              throw new TclNumArgsException( interp, 1, objv, "unknown ?command?" );
            }
            if ( objv.Length == 2 )
            {
              if ( (System.Object)interp.packageUnknown != null )
              {
                interp.setResult( interp.packageUnknown );
              }
            }
            else if ( objv.Length == 3 )
            {
              interp.packageUnknown = null;

              cmd = objv[2].ToString();
              if ( cmd.Length > 0 )
              {
                interp.packageUnknown = cmd;
              }
            }
            return TCL.CompletionCode.RETURN;
          }

        case OPT_VCOMPARE:
          {
            if ( objv.Length != 4 )
            {
              throw new TclNumArgsException( interp, 1, objv, "vcompare version1 version2" );
            }

            ver1 = objv[2].ToString();

            ver2 = objv[3].ToString();
            checkVersion( interp, ver1 );
            checkVersion( interp, ver2 );
            interp.setResult( compareVersions( ver1, ver2, null ) );
            return TCL.CompletionCode.RETURN;
          }

        case OPT_VERSIONS:
          {
            if ( objv.Length != 3 )
            {
              throw new TclNumArgsException( interp, 1, objv, "versions package" );
            }

            pkg = (Package)interp.packageTable[objv[2].ToString()];
            if ( pkg != null )
            {
              try
              {
                sbuf = new StringBuilder();
                once = false;
                for ( avail = pkg.avail; avail != null; avail = avail.next )
                {
                  once = true;
                  Util.appendElement( interp, sbuf, avail.version );
                }
                if ( once )
                {
                  interp.setResult( sbuf.ToString() );
                }
              }
              catch ( TclException e )
              {
                throw new TclRuntimeError( "unexpected TclException: " + e.Message, e );
              }
            }
            return TCL.CompletionCode.RETURN;
          }

        case OPT_VSATISFIES:
          {
            if ( objv.Length != 4 )
            {
              throw new TclNumArgsException( interp, 1, objv, "vsatisfies version1 version2" );
            }


            ver1 = objv[2].ToString();

            ver2 = objv[3].ToString();
            checkVersion( interp, ver1 );
            checkVersion( interp, ver2 );
            vsres = new VersionSatisfiesResult();
            compareVersions( ver1, ver2, vsres );
            interp.setResult( vsres.satisfies );
            return TCL.CompletionCode.RETURN;
          }

        default:
          {
            throw new TclRuntimeError( "TclIndex.get() error" );
          }

      } // end switch(opt)
      return TCL.CompletionCode.RETURN;
    }
Exemplo n.º 8
0
    internal static string pkgPresent( Interp interp, string pkgName, string version, bool exact )
    {
      Package pkg;
      VersionSatisfiesResult vsres = new VersionSatisfiesResult();
      int result;

      pkg = (Package)interp.packageTable[pkgName];
      if ( pkg != null )
      {
        if ( (System.Object)pkg.version != null )
        {

          // At this point we know that the package is present.  Make sure
          // that the provided version meets the current requirement.

          if ( (System.Object)version == null )
          {
            return pkg.version;
          }
          result = compareVersions( pkg.version, version, vsres );
          if ( ( vsres.satisfies && !exact ) || ( result == 0 ) )
          {
            return pkg.version;
          }
          throw new TclException( interp, "version conflict for package \"" + pkgName + "\": have " + pkg.version + ", need " + version );
        }
      }

      if ( (System.Object)version != null )
      {
        throw new TclException( interp, "package " + pkgName + " " + version + " is not present" );
      }
      else
      {
        throw new TclException( interp, "package " + pkgName + " is not present" );
      }
    }