1 #Region "Microsoft.VisualBasic::1e21ab1839f3e8e938e3801e9aaa66f8, Microsoft.VisualBasic.Core\Language\Language\Perl\Tools.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Module Functions
35     
36     '         Function: chomp, Pop, system
37     
38     '         Sub: (+3 Overloads) chomp, (+2 Overloads) Push
39     
40     
41     ' /********************************************************************************/
42
43 #End Region
44
45 Imports System.Runtime.CompilerServices
46 Imports System.Array
47 Imports Microsoft.VisualBasic.ComponentModel.DataSourceModel
48 Imports Microsoft.VisualBasic.ComponentModel.Collection
49
50 Namespace Language.Perl
51
52     ''' <summary>
53     ''' 
54     ''' </summary>
55     ''' <remarks>
56     ''' ##### last
57     ''' 
58     ''' The ``last`` command Is Like the ``break`` statement In C (As used In loops); **it immediately exits the Loop In question**. 
59     ''' If the ``LABEL`` Is omitted, the command refers To the innermost enclosing Loop. The last EXPR form, available starting 
60     ''' In Perl 5.18.0, allows a label name To be computed at run time, And Is otherwise identical To last ``LABEL``. 
61     ''' 
62     ''' **The Continue block, If any, Is Not executed**
63     ''' (Perl里面的``last``关键词相当于vb里面的``Exit Do``或者``Exit For``)
64     ''' 
65     ''' 匹配:``m/&lt;regexp>/`` (还可以简写为 /&lt;regexp>/, 略去 m)
66     ''' 替换:``s/&lt;pattern>/&lt;replacement>/``
67     ''' 转化:``tr/&lt;pattern>/&lt;replacemnt>/``
68     ''' </remarks>
69     Public Module Functions
70
71         ''' <summary>
72         ''' Treats ARRAY as a stack by appending the values of LIST to the end of ARRAY. The length of ARRAY 
73         ''' increases by the length of LIST. Has the same effect as
74         ''' 
75         ''' ```perl
76         ''' for my $value (LIST) {
77         '''     $ARRAY[++$#ARRAY] = $value;
78         ''' }
79         ''' ```
80         ''' 
81         ''' but Is more efficient. Returns the number of elements in the array following the completed push.
82         ''' Starting with Perl 5.14, an experimental feature allowed push to take a scalar expression. 
83         ''' This experiment has been deemed unsuccessful, And was removed as of Perl 5.24.
84         ''' </summary>
85         ''' <typeparam name="T"></typeparam>
86         ''' <param name="array"></param>
87         ''' <param name="x"></param>
88         ''' 
89         <Extension>
90         Public Sub Push(Of T)(ByRef array As T(), x As T)
91             ReDim Preserve array(array.Length)
92             array(array.Length - 1) = x
93         End Sub
94
95         ''' <summary>
96         ''' Treats ARRAY as a stack by appending the values of LIST to the end of ARRAY. The length of ARRAY 
97         ''' increases by the length of LIST. Has the same effect as
98         ''' 
99         ''' ```perl
100         ''' for my $value (LIST) {
101         '''     $ARRAY[++$#ARRAY] = $value;
102         ''' }
103         ''' ```
104         ''' 
105         ''' but Is more efficient. Returns the number of elements in the array following the completed push.
106         ''' Starting with Perl 5.14, an experimental feature allowed push to take a scalar expression. 
107         ''' This experiment has been deemed unsuccessful, And was removed as of Perl 5.24.
108         ''' </summary>
109         ''' <typeparam name="T"></typeparam>
110         ''' <param name="array"></param>
111         ''' <param name="LIST"></param>
112         <Extension>
113         Public Sub Push(Of T)(ByRef array As T(), LIST As IEnumerable(Of T))
114             Dim source As T() = LIST.ToArray
115             Dim tmp As T() = New T(array.Length + source.Length - 1) {}
116
117             Call ConstrainedCopy(array, Scan0, tmp, Scan0, array.Length)
118             Call ConstrainedCopy(source, Scan0, tmp, array.Length, source.Length)
119
120             array = tmp
121         End Sub
122
123         ''' <summary>
124         ''' ##### pop ARRAY
125         ''' 
126         ''' **pop**
127         ''' Pops And returns the last value of the array, shortening the array by one element.
128         ''' 
129         ''' Returns the undefined value If the array Is empty, although this may also happen at 
130         ''' other times. If ARRAY Is omitted, pops the @ARGV array In the main program, but the 
131         ''' @_ array In subroutines, just Like shift.
132         ''' 
133         ''' Starting with Perl 5.14, an experimental feature allowed pop to take a scalar expression. 
134         ''' This experiment has been deemed unsuccessful, And was removed as of Perl 5.24.
135         ''' </summary>
136         ''' <typeparam name="T"></typeparam>
137         ''' <param name="array"></param>
138         ''' <returns></returns>
139         <Extension>
140         Public Function Pop(Of T)(ByRef array As T()) As T
141             If array.IsNullOrEmpty Then
142                 Return Nothing
143             End If
144
145             Dim last As T = array(array.Length - 1)
146             ReDim Preserve array(array.Length - 1)
147         End Function
148
149         ''' <summary>
150         ''' Does exactly the same thing as exec, except that a fork is done first and the parent process waits for the 
151         ''' child process to exit. Note that argument processing varies depending on the number of arguments. If there 
152         ''' is more than one argument in LIST, or if LIST is an array with more than one value, starts the program 
153         ''' given by the first element of the list with arguments given by the rest of the list. If there is only one 
154         ''' scalar argument, the argument is checked for shell metacharacters, and if there are any, the entire argument 
155         ''' is passed to the system's command shell for parsing (this is /bin/sh -c on Unix platforms, but varies on 
156         ''' other platforms). If there are no shell metacharacters in the argument, it is split into words and passed 
157         ''' directly to execvp , which is more efficient. On Windows, only the system PROGRAM LIST syntax will reliably 
158         ''' avoid using the shell; system LIST , even with more than one element, will fall back to the shell if the 
159         ''' first spawn fails.
160         ''' Perl will attempt To flush all files opened For output before any operation that may Do a fork, but this 
161         ''' may Not be supported On some platforms (see perlport). To be safe, you may need To Set $ ($AUTOFLUSH In 
162         ''' English) Or Call the autoflush method Of IO:Handle on any open handles.
163         ''' The return value Is the exit status of the program as returned by the wait call. To get the actual exit 
164         ''' value, shift right by eight (see below). See also exec. This Is Not what you want to use to capture the 
165         ''' output from a command; for that you should use merely backticks Or qx//, as described in `STRING` in perlop. 
166         ''' Return value of -1 indicates a failure to start the program Or an error of the wait(2) system call 
167         ''' (inspect $! for the reason).
168         ''' If you 'd like to make system (and many other bits of Perl) die on error, have a look at the autodie pragma.
169         ''' Like exec, system allows you to lie to a program about its name if you use the system PROGRAM LIST syntax. 
170         ''' Again, see exec.
171         ''' </summary>
172         ''' <param name="CLI"></param>
173         ''' <returns></returns>
174         Public Function system(CLI As StringAs Integer
175             Return Interaction.Shell(CLI, AppWinStyle.NormalFocus, True)
176         End Function
177
178         ''' <summary>
179         ''' This safer version of chop removes any trailing string that corresponds to the current value of ``$/`` 
180         ''' (also known as ``$INPUT_RECORD_SEPARATOR`` in the English module). It returns the total number of characters 
181         ''' removed from all its arguments. It's often used to remove the newline from the end of an input record 
182         ''' when you're worried that the final record may be missing its newline. When in paragraph mode (``$/ = ''`` ), 
183         ''' it removes all trailing newlines from the string. When in slurp mode (``$/ = undef`` ) or fixed-length 
184         ''' record mode (``$/`` is a reference to an integer or the like; see perlvar), chomp won't remove anything.
185         ''' </summary>
186         ''' <param name="s"></param>
187         ''' <returns></returns>
188         <Extension>
189         Public Function chomp(ByRef s As StringAs String
190             s = s.Trim(vbCr, vbLf)
191             s = s.Trim(vbTab, " "c)
192
193             Return s
194         End Function
195
196         ''' <summary>
197         ''' If you chomp a ``list`` or ``array``, each element is chomped, and the total number of characters removed is returned.
198         ''' </summary>
199         ''' <param name="source"></param>
200         <Extension>
201         Public Sub chomp(ByRef source As IEnumerable(Of String))
202             Dim array As String() = source.ToArray
203
204             For i As Integer = 0 To array.Length - 1
205                 array(i).chomp
206             Next
207
208             source = array
209         End Sub
210
211         ''' <summary>
212         ''' If ``VARIABLE`` is a hash, it chomps the hash's values, but not its keys, resetting the each iterator 
213         ''' in the process.
214         ''' 
215         ''' You can actually chomp anything that's an ``lvalue``, including an assignment:
216         ''' 
217         ''' ```perl
218         ''' chomp(my $cwd = `pwd`);
219         ''' chomp(my $answer = &lt;STDIN>);
220         ''' ```
221         ''' </summary>
222         ''' <param name="hash"></param>
223         <Extension>
224         Public Sub chomp(ByRef hash As Dictionary(Of StringString))
225             For Each key As String In hash.Keys
226                 hash(key) = hash(key).chomp
227             Next
228         End Sub
229
230         ''' <summary>
231         ''' If ``VARIABLE`` is a hash, it chomps the hash's values, but not its keys, resetting the each iterator 
232         ''' in the process.
233         ''' 
234         ''' You can actually chomp anything that's an ``lvalue``, including an assignment:
235         ''' 
236         ''' ```perl
237         ''' chomp(my $cwd = `pwd`);
238         ''' chomp(my $answer = &lt;STDIN>);
239         ''' ```
240         ''' </summary>
241         ''' <param name="hash"></param>
242         <Extension>
243         Public Sub chomp(ByRef hash As Dictionary(Of NamedValue(Of String)))
244             For Each key As String In hash.Keys
245                 Dim x As NamedValue(Of String) = hash(key)
246                 hash(key) = New NamedValue(Of StringWith {
247                     .Name = key,
248                     .Value = x.Value.chomp,
249                     .Description = x.Description
250                 }
251             Next
252         End Sub
253     End Module
254 End Namespace