It is a double for loop scanning all the argument passed to the script and storing them in an array, ready to be used in the rest of the script itself.
Let's have a look at the code:
ARG_LOOP: # 1
foreach(@ARGV) # 2
for(my $i = 0; $i < 3; $i++) # 3
if(/(.*_$TAGS[$i])$IN_EXT$/) # 4
if(defined $files[$i]) # 5
print "You can't pass more than one $TAGS[$i] file to the script\n";
$files[$i] = $1; # 6
next ARG_LOOP; # 7
print "Unexpected argument detected\n"; # 8
1. A label is declared so that a "next" instruction could be used in the inner loop to skip to the next iteration for the outer loop.
2. Looping on all the element in the ARGV array, containing the arguments passed to the script. The current item is stored in the default $_ variable.
3. Internal loop: we are expecting three input parameter.
4. Each input parameter should respect a specific pattern: first part is seen as a block containing free text, then an underscore followed by a previously defined tag. The final part of the parameter is a previously defined INput EXTension. Notice the $ before the final slash: nothing is expected after the extension.
5. There should be exactly one input parameter for each defined tag. So we check if the current file has been already defined in a previous iteration. If this is the case, we print a message to the user (in the $help variable is showed how the script should be called) and return to the system.
6. A match has been found, and the file has not already be defined for the current tag. The (first and unique) block defined in the pattern is assigned to the current file element.
7. We stop the internal loop and give back the control to the next iteration of the external loop.
8. We shouldn't normally get here, since all expected input parameter should match all the stored tags. If we find a parameter not matching any tag, we print some helpful comment and return to the system.