public PairwiseTuple[] Generate(out PictExecutionInformation executionInformation) { string[][] results; string pictModel = (string)this.Visit(model); // PictConstants.Trace("Pict model: {0}", model.Comment); string fn = settings.CanCache ? PictConstants.CacheFileName : null; using (PictRunner exec = new PictRunner(fn)) { results = exec.MaybeExecutePict(settings, pictModel); executionInformation = exec.LastExecutionInformation; if (settings.RandomizeGeneration) { settings.RandomSeed = executionInformation.RandomSeed; // NOTE: not setting settings.RandomSeedSpecified } } // PictConstants.Trace("Results of executing PICT: {0}", results.Substring(0, Math.Min(255, results.Length))); int tupleLen = results[0].Length; PairwiseTuple[] tuples = new PairwiseTuple[results.Length - 1]; // skip the header string[] fields = results[0]; for (int tupleNumber = 0; tupleNumber < tuples.Length; ++tupleNumber) { // the line we access is actually '1-indexed': the first row is the fields string[] line = results[tupleNumber + 1]; PairwiseTuple pt = new PairwiseTuple(fields); for (int currentField = 0; currentField < tupleLen; ++currentField) { PairwiseValue value = context.FindValue(currentField, line[currentField]); pt.Add(model.Parameters[currentField].Name, value); } tuples[tupleNumber] = pt; } return(tuples); }
public string[][] MaybeExecutePict(PairwiseSettings settings, string inputContent) { string key = GetHash(settings, inputContent); if (cache != null && settings.CanCache && cache.Contains(key)) { PictConstants.Trace("Found key, using cached value!"); this.last = cache[key]; return(last.ParsedOutput); } string randomFileName = Guid.NewGuid().ToString() + PictConstants.TempFileSuffix; using (StreamWriter sw = new StreamWriter(randomFileName)) { sw.WriteLine("# " + randomFileName + " " + settings.GetPictArgs()); sw.WriteLine(inputContent); } try { string[][] ret = AlwaysExecutePictOnFileName(randomFileName, settings); if (cache != null && settings.CanCache) { // always execute pict set last correctly cache[key] = this.LastExecutionInformation; } return(ret); } finally { File.Delete(randomFileName); } }
string[][] AlwaysExecutePictOnFileNameCore(string modelFileName, string argsForPict, PairwiseSettings settings) { if (modelFileName == null) { throw new ArgumentNullException("modelFileName"); } if (argsForPict == null) { argsForPict = ""; } else { argsForPict = argsForPict.Trim(); } if (!File.Exists(modelFileName)) { throw new FileNotFoundException("Pict model not found: " + modelFileName); } ProcessStartInfo psi = new ProcessStartInfo(); // this will throw if not found psi.FileName = PairwiseSettings.GetPictExecutableFullPath(); PictConstants.Trace("Attempting to use {0}", psi.FileName); psi.Arguments = (MaybeQuote(modelFileName) + " " + argsForPict).Trim(); psi.UseShellExecute = false; psi.RedirectStandardError = true; psi.RedirectStandardOutput = true; DateTime started = DateTime.Now; PictConstants.Trace("Starting " + psi.Arguments); using (Process process = Process.Start(psi)) { PictConstants.Trace("Started successfully"); string[][] parsed = Split(process.StandardOutput, PictConstants.OutputValueSeparator); process.StandardOutput.Close(); int seed = 0; bool wasRandom = false; process.WaitForExit(); PictConstants.Trace("Done waiting for exit"); TimeSpan elapsed = DateTime.Now - started; PictConstants.Trace("Elapsed time: {0}", elapsed); // note: there's some better way to do this?? string allStdErr = process.StandardError.ReadToEnd(); process.StandardError.Close(); if (allStdErr.Length != 0) { PictConstants.Trace("Begin stderr/{0}/end stderr*", allStdErr); ArrayList msgs = new ArrayList(); foreach (string s in allStdErr.Split('\r', '\n')) { if (s.Trim().Length != 0) { msgs.Add(s.TrimEnd()); } } for (int i = 0; i < msgs.Count; ++i) { string message = (string)msgs[i]; if (message.Trim().Length == 0) { continue; } if (message.StartsWith(PictConstants.UsedSeedMessage)) { message = message.Replace(PictConstants.UsedSeedMessage, "").Trim(); wasRandom = true; seed = int.Parse(message, PictConstants.Culture); PictConstants.Trace("{0} {1}", wasRandom, seed); } else if (message.StartsWith(PictConstants.WarningMessage) || (message.IndexOf("arning") != -1)) { while (i < msgs.Count - 1 && ((string)msgs[i + 1]).StartsWith(" ")) { message += Environment.NewLine + ((string)msgs[++i]); } if (settings != null) { settings.OnWarning(message.Trim()); } } else { PictConstants.Trace("throwing /{0}/", message.Trim()); throw new PairwiseException(message.Trim()); } } } // string stdout = sb.ToString(); PictExecutionInformation pei = new PictExecutionInformation(); pei.FileName = modelFileName; pei.Generated = DateTime.Now; pei.Options = argsForPict; pei.RandomSeedSpecified = wasRandom; // pei.RawOutput = stdout; pei.ParsedOutput = parsed; if (wasRandom) { pei.RandomSeed = seed; } this.last = pei; return(parsed); } // end using(Process) }