#!/usr/bin/perl -w
#
#  skudparser -- parse something for skud
#
#  2001/02/28 Rich Lafferty <rich@alcor.concordia.ca> -- initial version
#
#  Released into the public domain.
#
# ---------------------------------------------------------------
# Skud wrote:
#
#  Anyone got a clever idea for how to split up the following (user input)
#  string into a list of subroutines with their args?
#
#  a,b(),c(1),d(1,2,3), e, ), f(), g(1), h(1,2,3), i(1, 2, 3), j(1, 2,3),
#       k(","),l(","," "), m(")"), n("),")
#
#  This should return an array with the following elements:
#
#  a
#  b()
#  c(1)
#  d(1,2,3)
#  e
#  )
#  f()
#  g(1)
#  ...
#  n("),")
#
# ---------------------------------------------------------------
#
# Note to self: *Having* a good regexp engine doesn't mean having 
#               to *use* regular expressions.

use strict;

sub parse ($) {
    my @line = split('', $_[0]);
    my (@outdata, $chunk);
    my ($qq, $q, $p, $i) = (0,0,0,0); # ", ', (
    
    for (@line) {
       $i++;

       # mind our p's and q's
       die qq|Impossible count ["$qq" '$q' ($p)] at character $i ('$_')|
           if $qq < 0 or $q < 0 or $p < 0 or $q > 1 or $qq > 1;

       # parens nest
       $p++ if $_ eq '(' and !$q and !$qq;
       $p-- if $_ eq ')' and $p and !$q and !$qq;

       # quotes don't nest
       $qq = !$qq if $_ eq q|"| and !$q;
       $q  = !$q  if $_ eq q|'| and !$qq;

       # ignore spaces outside of quotes
       next if $_ eq ' ' and !$qq and !$q;

       if ($_ eq ',' and !$p and !$q and !$qq) {
           # not inside anything so this one's a delimiter
           push @outdata, $chunk;
           $chunk = undef;
           next;
       }

       # keep what we've got
       $chunk .= $_;
    }

    push @outdata, $chunk; # no comma following last chunk!
    return @outdata;

}

# test data

my $input = q|a,b(),c(1),d(1,2,3), e, ), f("  "), g(1), h(1,2,3), i(1, 2, 3), j(1, 2,3), k(","),l('","'," "), m(')'), n("),'")|;

my $noquote = q|a,b(),c(1),d(1,2,3), e, ), f(  ), g(1), h(1,2,3), i(1, 2, 3), j(1, 2,3), k(,),l(,, ), m()), n(),)|;

my @hlagh = parse($input);

for (@hlagh) {
    print "$_\n";
}


