MegaBites-AI/Windows-powershell
0372
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System;5using System.Collections;6using System.Collections.Generic;7using System.IO;8using System.Linq;9using System.Management.Automation;10using System.Management.Automation.Internal;11using System.Management.Automation.Runspaces;12using Microsoft.PowerShell.Commands;13 14namespace Microsoft.PowerShell.Commands.Internal.Format15{16 /// <summary>17 /// Base class defining the formatting context and the18 /// formatting context manager (stack based)19 /// </summary>20 internal class InnerFormatShapeCommandBase : ImplementationCommandBase21 {22 /// <summary>23 /// Constructor to set up the formatting context.24 /// </summary>25 internal InnerFormatShapeCommandBase()26 {27 contextManager.Push(FormattingContextState.none);28 }29 30 /// <summary>31 /// Enum listing the possible states the context is in.32 /// </summary>33 internal enum FormattingContextState { none, document, group }34 35 /// <summary>36 /// Context manager: stack to keep track in which context37 /// the formatter is.38 /// </summary>39 protected Stack<FormattingContextState> contextManager = new Stack<FormattingContextState>();40 }41 42 /// <summary>43 /// Core inner implementation for format/xxx commands.44 /// </summary>45 internal class InnerFormatShapeCommand : InnerFormatShapeCommandBase46 {47 /// <summary>48 /// Constructor to glue to the CRO.49 /// </summary>50 internal InnerFormatShapeCommand(FormatShape shape)51 {52 _shape = shape;53 }54 55 internal static int FormatEnumerationLimit()56 {57 object enumLimitVal = null;58 try59 {60 // Win8: 19250461 if (LocalPipeline.GetExecutionContextFromTLS() != null)62 {63 enumLimitVal = LocalPipeline.GetExecutionContextFromTLS()64 .SessionState.PSVariable65 .GetValue("global:" + InitialSessionState.FormatEnumerationLimit);66 }67 }68 // Eat the following exceptions, enumerationLimit will use the default value69 catch (ProviderNotFoundException)70 {71 }72 catch (ProviderInvocationException)73 {74 }75 76 // if $global:FormatEnumerationLimit is an int, overwrite the default value77 return enumLimitVal is int ? (int)enumLimitVal : InitialSessionState.DefaultFormatEnumerationLimit;78 }79 80 internal override void BeginProcessing()81 {82 base.BeginProcessing();83 84 // Get the Format Enumeration Limit.85 _enumerationLimit = InnerFormatShapeCommand.FormatEnumerationLimit();86 87 _expressionFactory = new PSPropertyExpressionFactory();88 89 _formatObjectDeserializer = new FormatObjectDeserializer(this.TerminatingErrorContext);90 }91 92 /// <summary>93 /// Execution entry point.94 /// </summary>95 internal override void ProcessRecord()96 {97 _typeInfoDataBase = this.OuterCmdlet().Context.FormatDBManager.GetTypeInfoDataBase();98 99 PSObject so = this.ReadObject();100 if (so == null || so == AutomationNull.Value)101 return;102 103 IEnumerable e = PSObjectHelper.GetEnumerable(so);104 if (e == null)105 {106 ProcessObject(so);107 return;108 }109 110 // we have an IEnumerable, we have to decide if to expand, if at all111 EnumerableExpansion expansionState = this.GetExpansionState(so);112 113 switch (expansionState)114 {115 case EnumerableExpansion.EnumOnly:116 {117 foreach (object obj in e)118 {119 ProcessObject(PSObjectHelper.AsPSObject(obj));120 }121 }122 123 break;124 case EnumerableExpansion.Both:125 {126 var objs = e.Cast<object>().ToArray();127 128 ProcessCoreOutOfBand(so, objs.Length);129 foreach (object obj in objs)130 {131 ProcessObject(PSObjectHelper.AsPSObject(obj));132 }133 }134 135 break;136 default:137 {138 // do not enumerate at all (CoreOnly)139 ProcessObject(so);140 }141 142 break;143 }144 }145 146 private EnumerableExpansion GetExpansionState(PSObject so)147 {148 // if the command line swtich has been specified, use this as an override149 if (_parameters != null && _parameters.expansion.HasValue)150 {151 return _parameters.expansion.Value;152 }153 154 // check if we have an expansion entry in format.mshxml155 var typeNames = so.InternalTypeNames;156 return DisplayDataQuery.GetEnumerableExpansionFromType(157 _expressionFactory, _typeInfoDataBase, typeNames);158 }159 160 private void ProcessCoreOutOfBand(PSObject so, int count)161 {162 // emit some description header163 SendCommentOutOfBand(FormatAndOut_format_xxx.IEnum_Header);164 165 // emit the object as out of band166 ProcessOutOfBand(so, isProcessingError: false);167 168 string msg;169 // emit a comment to signal that the next N objects are from the IEnumerable170 switch (count)171 {172 case 0:173 {174 msg = FormatAndOut_format_xxx.IEnum_NoObjects;175 }176 177 break;178 case 1:179 {180 msg = FormatAndOut_format_xxx.IEnum_OneObject;181 }182 183 break;184 default:185 {186 msg = StringUtil.Format(FormatAndOut_format_xxx.IEnum_ManyObjects, count);187 }188 189 break;190 }191 192 SendCommentOutOfBand(msg);193 }194 195 private void SendCommentOutOfBand(string msg)196 {197 FormatEntryData fed = OutOfBandFormatViewManager.GenerateOutOfBandObjectAsToString(PSObjectHelper.AsPSObject(msg));198 if (fed != null)199 {200 this.WriteObject(fed);201 }202 }203 204 /// <summary>205 /// Execute formatting on a single object.206 /// </summary>207 /// <param name="so">Object to process.</param>208 private void ProcessObject(PSObject so)209 {210 // we do protect against reentrancy, assuming211 // no fancy multiplexing212 if (_formatObjectDeserializer.IsFormatInfoData(so))213 {214 // we are already formatted...215 this.WriteObject(so);216 return;217 }218 219 // if objects have to be treated as out of band, just220 // bail now221 // this is the case of objects coming before the222 // context manager is properly set223 if (ProcessOutOfBandObjectOutsideDocumentSequence(so))224 {225 return;226 }227 228 // if we haven't started yet, need to do so229 FormattingContextState ctx = contextManager.Peek();230 if (ctx == FormattingContextState.none)231 {232 // initialize the view manager233 _viewManager.Initialize(this.TerminatingErrorContext, _expressionFactory, _typeInfoDataBase, so, _shape, _parameters);234 235 // add the start message to output queue236 WriteFormatStartData(so);237 238 // enter the document context239 contextManager.Push(FormattingContextState.document);240 }241 242 // if we are here, we are either in the document document, or in a group243 244 // since we have a view now, we check if objects should be treated as out of band245 if (ProcessOutOfBandObjectInsideDocumentSequence(so))246 {247 return;248 }249 250 // check if we have to enter or exit a group251 GroupTransition transition = ComputeGroupTransition(so);252 if (transition == GroupTransition.enter)253 {254 // insert the group start marker255 PushGroup(so);256 this.WritePayloadObject(so);257 }258 else if (transition == GroupTransition.exit)259 {260 this.WritePayloadObject(so);261 // insert the group end marker262 PopGroup();263 }264 else if (transition == GroupTransition.startNew)265 {266 // Add newline before each group except first267 WriteNewLineObject();268 269 // double transition270 PopGroup(); // exit the current one271 PushGroup(so); // start a sibling group272 this.WritePayloadObject(so);273 }274 else // none, we did not have any transitions, just push out the data275 {276 this.WritePayloadObject(so);277 }278 }279 280 private void WriteNewLineObject()281 {282 FormatEntryData fed = new FormatEntryData();283 fed.outOfBand = true;284 285 ComplexViewEntry cve = new ComplexViewEntry();286 FormatEntry fe = new FormatEntry();287 cve.formatValueList.Add(fe);288 289 // Formating system writes newline before each object290 // so no need to add newline here like:291 // fe.formatValueList.Add(new FormatNewLine());292 fed.formatEntryInfo = cve;293 294 this.WriteObject(fed);295 }296 297 private bool ShouldProcessOutOfBand298 {299 get300 {301 if (_shape == FormatShape.Undefined || _parameters == null)302 {303 return true;304 }305 306 return !_parameters.forceFormattingAlsoOnOutOfBand;307 }308 }309 310 private bool ProcessOutOfBandObjectOutsideDocumentSequence(PSObject so)311 {312 if (!ShouldProcessOutOfBand)313 {314 return false;315 }316 317 if (so.InternalTypeNames.Count == 0)318 {319 return false;320 }321 322 List<ErrorRecord> errors;323 var fed = OutOfBandFormatViewManager.GenerateOutOfBandData(this.TerminatingErrorContext, _expressionFactory,324 _typeInfoDataBase, so, _enumerationLimit, false, out errors);325 WriteErrorRecords(errors);326 327 if (fed != null)328 {329 this.WriteObject(fed);330 return true;331 }332 333 return false;334 }335 336 private bool ProcessOutOfBandObjectInsideDocumentSequence(PSObject so)337 {338 if (!ShouldProcessOutOfBand)339 {340 return false;341 }342 343 var typeNames = so.InternalTypeNames;344 if (_viewManager.ViewGenerator.IsObjectApplicable(typeNames))345 {346 return false;347 }348 349 return ProcessOutOfBand(so, isProcessingError: false);350 }351 352 private bool ProcessOutOfBand(PSObject so, bool isProcessingError)353 {354 List<ErrorRecord> errors;355 FormatEntryData fed = OutOfBandFormatViewManager.GenerateOutOfBandData(this.TerminatingErrorContext, _expressionFactory,356 _typeInfoDataBase, so, _enumerationLimit, true, out errors);357 if (!isProcessingError)358 WriteErrorRecords(errors);359 360 if (fed != null)361 {362 this.WriteObject(fed);363 return true;364 }365 366 return false;367 }368 369 protected void WriteInternalErrorMessage(string message)370 {371 FormatEntryData fed = new FormatEntryData();372 fed.outOfBand = true;373 374 ComplexViewEntry cve = new ComplexViewEntry();375 FormatEntry fe = new FormatEntry();376 cve.formatValueList.Add(fe);377 378 fe.formatValueList.Add(new FormatNewLine());379 380 // get a field for the message381 FormatTextField ftf = new FormatTextField();382 ftf.text = message;383 fe.formatValueList.Add(ftf);384 385 fe.formatValueList.Add(new FormatNewLine());386 387 fed.formatEntryInfo = cve;388 389 this.WriteObject(fed);390 }391 392 private void WriteErrorRecords(List<ErrorRecord> errorRecordList)393 {394 if (errorRecordList == null)395 return;396 397 // NOTE: for the time being we directly process error records.398 // This is should change if we hook up error pipelines; for the399 // time being, this achieves partial results.400 //401 // see NTRAID#Windows OS Bug-932722-2004/10/21-kevinloo ("Output: SS: Swallowing exceptions")402 foreach (ErrorRecord errorRecord in errorRecordList)403 {404 // we are recursing on formatting errors: isProcessingError == true405 ProcessOutOfBand(PSObjectHelper.AsPSObject(errorRecord), true);406 }407 }408 409 internal override void EndProcessing()410 {411 // need to pop all the contexts, in case the transmission sequence412 // was interrupted413 while (true)414 {415 FormattingContextState ctx = contextManager.Peek();416 417 if (ctx == FormattingContextState.none)418 {419 break; // we emerged and we are done420 }421 else if (ctx == FormattingContextState.group)422 {423 PopGroup();424 }425 else if (ctx == FormattingContextState.document)426 {427 // inject the end format information428 FormatEndData endFormat = new FormatEndData();429 this.WriteObject(endFormat);430 contextManager.Pop();431 }432 }433 }434 435 internal void SetCommandLineParameters(FormattingCommandLineParameters commandLineParameters)436 {437 Diagnostics.Assert(commandLineParameters != null, "the caller has to pass a valid instance");438 _parameters = commandLineParameters;439 }440 441 /// <summary>442 /// Group transitions:443 /// none: stay in the same group444 /// enter: start a new group445 /// exit: exit from the current group.446 /// </summary>447 private enum GroupTransition { none, enter, exit, startNew }448 449 /// <summary>450 /// Compute the group transition, given an input object.451 /// </summary>452 /// <param name="so">Object received from the input pipeline.</param>453 /// <returns>GroupTransition enumeration.</returns>454 private GroupTransition ComputeGroupTransition(PSObject so)455 {456 // check if we have to start a group457 FormattingContextState ctx = contextManager.Peek();458 if (ctx == FormattingContextState.document)459 {460 // prime the grouping algorithm461 _viewManager.ViewGenerator.UpdateGroupingKeyValue(so);462 463 // need to start a group, but we are not in one464 return GroupTransition.enter;465 }466 467 // check if we need to start another group and keep track468 // of the current value for the grouping property469 return _viewManager.ViewGenerator.UpdateGroupingKeyValue(so) ? GroupTransition.startNew : GroupTransition.none;470 }471 472 private void WriteFormatStartData(PSObject so)473 {474 FormatStartData startFormat = _viewManager.ViewGenerator.GenerateStartData(so);475 this.WriteObject(startFormat);476 }477 478 /// <summary>479 /// Write a payplad object by properly wrapping it into480 /// a FormatEntry object.481 /// </summary>482 /// <param name="so">Object to process.</param>483 private void WritePayloadObject(PSObject so)484 {485 Diagnostics.Assert(so != null, "object so cannot be null");486 FormatEntryData fed = _viewManager.ViewGenerator.GeneratePayload(so, _enumerationLimit);487 fed.writeStream = so.WriteStream;488 this.WriteObject(fed);489 490 List<ErrorRecord> errors = _viewManager.ViewGenerator.ErrorManager.DrainFailedResultList();491 WriteErrorRecords(errors);492 }493 494 /// <summary>495 /// Inject the start group information496 /// and push group context on stack.497 /// </summary>498 /// <param name="firstObjectInGroup">current pipeline object499 /// that is starting the group</param>500 private void PushGroup(PSObject firstObjectInGroup)501 {502 GroupStartData startGroup = _viewManager.ViewGenerator.GenerateGroupStartData(firstObjectInGroup, _enumerationLimit);503 this.WriteObject(startGroup);504 contextManager.Push(FormattingContextState.group);505 }506 507 /// <summary>508 /// Inject the end group information509 /// and pop group context out of stack.510 /// </summary>511 private void PopGroup()512 {513 GroupEndData endGroup = _viewManager.ViewGenerator.GenerateGroupEndData();514 this.WriteObject(endGroup);515 contextManager.Pop();516 }517 518 /// <summary>519 /// The formatting shape this formatter emits.520 /// </summary>521 private readonly FormatShape _shape;522 523 #region expression factory524 525 /// <exception cref="ParseException"></exception>526 internal ScriptBlock CreateScriptBlock(string scriptText)527 {528 var scriptBlock = this.OuterCmdlet().InvokeCommand.NewScriptBlock(scriptText);529 scriptBlock.DebuggerStepThrough = true;530 return scriptBlock;531 }532 533 private PSPropertyExpressionFactory _expressionFactory;534 #endregion535 536 private FormatObjectDeserializer _formatObjectDeserializer;537 538 private TypeInfoDataBase _typeInfoDataBase = null;539 540 private FormattingCommandLineParameters _parameters = null;541 private readonly FormatViewManager _viewManager = new FormatViewManager();542 543 private int _enumerationLimit = InitialSessionState.DefaultFormatEnumerationLimit;544 }545 546 /// <summary>547 /// </summary>548 public class OuterFormatShapeCommandBase : FrontEndCommandBase549 {550 #region Command Line Switches551 552 /// <summary>553 /// Optional, non positional parameter to specify the554 /// group by property.555 /// </summary>556 [Parameter]557 public object GroupBy { get; set; } = null;558 559 /// <summary>560 /// Optional, non positional parameter.561 /// </summary>562 /// <value></value>563 [Parameter]564 public string View { get; set; } = null;565 566 /// <summary>567 /// Optional, non positional parameter.568 /// </summary>569 /// <value></value>570 [Parameter]571 public SwitchParameter ShowError572 {573 get574 {575 if (showErrorsAsMessages.HasValue)576 return showErrorsAsMessages.Value;577 return false;578 }579 580 set581 {582 showErrorsAsMessages = value;583 }584 }585 586 internal bool? showErrorsAsMessages = null;587 588 /// <summary>589 /// Optional, non positional parameter.590 /// </summary>591 /// <value></value>592 [Parameter]593 public SwitchParameter DisplayError594 {595 get596 {597 if (showErrorsInFormattedOutput.HasValue)598 return showErrorsInFormattedOutput.Value;599 return false;600 }601 602 set603 {604 showErrorsInFormattedOutput = value;605 }606 }607 608 internal bool? showErrorsInFormattedOutput = null;609 610 /// <summary>611 /// Optional, non positional parameter.612 /// </summary>613 /// <value></value>614 [Parameter]615 public SwitchParameter Force616 {617 get { return _forceFormattingAlsoOnOutOfBand; }618 619 set { _forceFormattingAlsoOnOutOfBand = value; }620 }621 622 private bool _forceFormattingAlsoOnOutOfBand;623 624 /// <summary>625 /// Optional, non positional parameter.626 /// </summary>627 /// <value></value>628 [Parameter]629 [ValidateSet(EnumerableExpansionConversion.CoreOnlyString,630 EnumerableExpansionConversion.EnumOnlyString,631 EnumerableExpansionConversion.BothString, IgnoreCase = true)]632 public string Expand { get; set; } = null;633 634 internal EnumerableExpansion? expansion = null;635 636 internal EnumerableExpansion? ProcessExpandParameter()637 {638 EnumerableExpansion? retVal = null;639 if (string.IsNullOrEmpty(Expand))640 {641 return null;642 }643 644 EnumerableExpansion temp;645 bool success = EnumerableExpansionConversion.Convert(Expand, out temp);646 if (!success)647 {648 // this should never happen, since we use the [ValidateSet] attribute649 // NOTE: this is an exception that should never be triggered650 throw PSTraceSource.NewArgumentException("Expand", FormatAndOut_MshParameter.IllegalEnumerableExpansionValue);651 }652 653 retVal = temp;654 return retVal;655 }656 657 internal MshParameter ProcessGroupByParameter()658 {659 if (GroupBy != null)660 {661 TerminatingErrorContext invocationContext =662 new TerminatingErrorContext(this);663 ParameterProcessor processor = new ParameterProcessor(new FormatGroupByParameterDefinition());664 List<MshParameter> groupParameterList =665 processor.ProcessParameters(new object[] { GroupBy },666 invocationContext);667 668 if (groupParameterList.Count != 0)669 return groupParameterList[0];670 }671 672 return null;673 }674 675 #endregion676 677 /// <summary>678 /// </summary>679 protected override void BeginProcessing()680 {681 InnerFormatShapeCommand innerFormatCommand =682 (InnerFormatShapeCommand)this.implementation;683 684 // read command line switches and pass them to the inner command685 FormattingCommandLineParameters parameters = GetCommandLineParameters();686 innerFormatCommand.SetCommandLineParameters(parameters);687 688 // must call base class for further processing689 base.BeginProcessing();690 }691 692 /// <summary>693 /// It reads the command line switches and collects them into a694 /// FormattingCommandLineParameters instance, ready to pass to the695 /// inner format command.696 /// </summary>697 /// <returns>Parameters collected in unified manner.</returns>698 internal virtual FormattingCommandLineParameters GetCommandLineParameters()699 {700 return null;701 }702 703 internal void ReportCannotSpecifyViewAndProperty()704 {705 string msg = StringUtil.Format(FormatAndOut_format_xxx.CannotSpecifyViewAndPropertyError);706 707 ErrorRecord errorRecord = new ErrorRecord(708 new InvalidDataException(),709 "FormatCannotSpecifyViewAndProperty",710 ErrorCategory.InvalidArgument,711 null);712 713 errorRecord.ErrorDetails = new ErrorDetails(msg);714 this.ThrowTerminatingError(errorRecord);715 }716 }717 718 /// <summary>719 /// </summary>720 public class OuterFormatTableAndListBase : OuterFormatShapeCommandBase721 {722 #region Command Line Switches723 724 /// <summary>725 /// Positional parameter for properties, property sets and table sets726 /// specified on the command line.727 /// The parameter is optional, since the defaults728 /// will be determined using property sets, etc.729 /// </summary>730 [Parameter(Position = 0)]731 [ValidateNotNullOrEmpty]732 public object[] Property { get; set; }733 734 /// <summary>735 /// Optional parameter for excluding properties from formatting.736 /// </summary>737 [Parameter]738 public string[] ExcludeProperty { get; set; }739 740 #endregion741 742 internal override FormattingCommandLineParameters GetCommandLineParameters()743 {744 FormattingCommandLineParameters parameters = new FormattingCommandLineParameters();745 746 GetCommandLineProperties(parameters, false);747 parameters.groupByParameter = this.ProcessGroupByParameter();748 749 parameters.forceFormattingAlsoOnOutOfBand = this.Force;750 if (this.showErrorsAsMessages.HasValue)751 parameters.showErrorsAsMessages = this.showErrorsAsMessages;752 if (this.showErrorsInFormattedOutput.HasValue)753 parameters.showErrorsInFormattedOutput = this.showErrorsInFormattedOutput;754 755 parameters.expansion = ProcessExpandParameter();756 757 return parameters;758 }759 760 internal void GetCommandLineProperties(FormattingCommandLineParameters parameters, bool isTable)761 {762 // Check View conflicts first (before any auto-expansion)763 if (!string.IsNullOrEmpty(this.View))764 {765 // View cannot be used with Property or ExcludeProperty766 if ((Property is not null && Property.Length != 0) || (ExcludeProperty is not null && ExcludeProperty.Length != 0))767 {768 ReportCannotSpecifyViewAndProperty();769 }770 771 parameters.viewName = this.View;772 }773 774 if (Property != null)775 {776 CommandParameterDefinition def;777 778 if (isTable)779 def = new FormatTableParameterDefinition();780 else781 def = new FormatListParameterDefinition();782 ParameterProcessor processor = new ParameterProcessor(def);783 TerminatingErrorContext invocationContext = new TerminatingErrorContext(this);784 785 parameters.mshParameterList = processor.ProcessParameters(Property, invocationContext);786 }787 788 if (ExcludeProperty is not null)789 {790 parameters.excludePropertyFilter = new PSPropertyExpressionFilter(ExcludeProperty);791 792 // ExcludeProperty implies -Property * for better UX793 if (Property is null || Property.Length == 0)794 {795 CommandParameterDefinition def = isTable796 ? new FormatTableParameterDefinition()797 : new FormatListParameterDefinition();798 ParameterProcessor processor = new ParameterProcessor(def);799 TerminatingErrorContext invocationContext = new TerminatingErrorContext(this);800 801 parameters.mshParameterList = processor.ProcessParameters(new object[] { "*" }, invocationContext);802 }803 }804 }805 }806 807 /// <summary>808 /// </summary>809 public class OuterFormatTableBase : OuterFormatTableAndListBase810 {811 #region Command Line Switches812 813 /// <summary>814 /// Optional, non positional parameter.815 /// </summary>816 /// <value></value>817 [Parameter]818 public SwitchParameter AutoSize819 {820 get821 {822 if (_autosize.HasValue)823 return _autosize.Value;824 return false;825 }826 827 set828 {829 _autosize = value;830 }831 }832 833 private bool? _autosize = null;834 835 /// <summary>836 /// Gets or sets if header is repeated per screen.837 /// </summary>838 [Parameter]839 public SwitchParameter RepeatHeader { get; set; }840 841 /// <summary>842 /// Optional, non positional parameter.843 /// </summary>844 /// <value></value>845 [Parameter]846 public SwitchParameter HideTableHeaders847 {848 get849 {850 if (_hideHeaders.HasValue)851 return _hideHeaders.Value;852 return false;853 }854 855 set856 {857 _hideHeaders = value;858 }859 }860 861 private bool? _hideHeaders = null;862 863 /// <summary>864 /// Optional, non positional parameter.865 /// </summary>866 /// <value></value>867 [Parameter]868 public SwitchParameter Wrap869 {870 get871 {872 if (_multiLine.HasValue)873 return _multiLine.Value;874 return false;875 }876 877 set878 {879 _multiLine = value;880 }881 }882 883 private bool? _multiLine = null;884 885 #endregion886 internal override FormattingCommandLineParameters GetCommandLineParameters()887 {888 FormattingCommandLineParameters parameters = new FormattingCommandLineParameters();889 890 GetCommandLineProperties(parameters, true);891 parameters.forceFormattingAlsoOnOutOfBand = this.Force;892 if (this.showErrorsAsMessages.HasValue)893 parameters.showErrorsAsMessages = this.showErrorsAsMessages;894 if (this.showErrorsInFormattedOutput.HasValue)895 parameters.showErrorsInFormattedOutput = this.showErrorsInFormattedOutput;896 897 parameters.expansion = ProcessExpandParameter();898 899 if (_autosize.HasValue)900 parameters.autosize = _autosize.Value;901 902 if (RepeatHeader)903 {904 parameters.repeatHeader = true;905 }906 907 parameters.groupByParameter = this.ProcessGroupByParameter();908 909 TableSpecificParameters tableParameters = new TableSpecificParameters();910 parameters.shapeParameters = tableParameters;911 912 if (_hideHeaders.HasValue)913 {914 tableParameters.hideHeaders = _hideHeaders.Value;915 }916 917 if (_multiLine.HasValue)918 {919 tableParameters.multiLine = _multiLine.Value;920 }921 922 return parameters;923 }924 }925}926 