[squeak-dev] Improving command line argument processing

David T. Lewis lewis at mail.msen.com
Fri Jun 12 02:17:53 UTC 2020


Hi Subbu,

One follow up note on this topic, slightly off topic - the vmrun 
shell script that I have previously shared on the list has a bug
that affects the command line arguments. On the last line of the
script, the argument list needs to be enclused in quotes, otherwise
it will not let you pass a command line parameter that contains
a space character.

I am attaching a fixed version. The only change is on the last
line of the shell script:

  exec ${VM} "$@"

Dave


On Tue, Jun 09, 2020 at 11:21:21AM +0530, K K Subbu wrote:
> On 09/06/20 4:56 am, David T. Lewis wrote:
> >According to the -help message from the VM:
> >
> >$ squeak -help
> >Usage: /usr/local/lib/squeak/4.19.1-3780/squeakvm [<option>...] 
> >[<imageName> [<argument>...]]
> >        /usr/local/lib/squeak/4.19.1-3780/squeakvm [<option>...] -- 
> >        [<argument>...]
> >
> >And a note toward the end of the help message says:
> >
> >   Precede <arguments> by `--' to use default image.
> 
> Ha! I now see the cause for confusion. Here arguments refers to image's 
> arguments not vm's options.
> 
> >
> >The above does not tell you explicitly how to parse this:
> >
> >   $ squeak squeak.image -- arg1 arg2 arg3
> >  
> >But if you consider that the VM is parsing the command line in the normal
> >manner up to the '--' token, and then passing the rest on the the image
> >as arguments, then the behavior seems quite reasonable.
> The vm option parsing stops when at the first word which does not begin 
> with - or -- *which ever occurs earlier*. In your example, vm options 
> will terminate at squeak.image and not see the -- coming after it. The 
> -- will parse as a image arg word and passed as such to the image.
> 
> As best as I could make out, the usage syntax is:
> 
>    <vm> <vmopt>* [--] [<file.image>] <image-args>*
>    <vmopt> = -<letter> | --<word>
> 
> The [--] is needed to mark the end of <vmopt> only when <image> or the 
> first <image-arg> begins with - (unlikely in interactive but possible in 
> shell scripts). The vm does check if the first non-option word ends in 
> *.image. If not, it uses ${SQUEAK_IMAGE:-squeak.image} and passes the 
> remaining args to this image.
> 
> >The need for '--' for disambiguation remains, partly because of the Squeak
> >convention of allowing an optional start script to be specified after the
> >image name.  You need to have some way of determining if 'arg1' was 
> >intended
> >as an argument for the image to process, or if it was intended as the name
> >of a script document to be evaluated at image startup time.
> 
> Image arg parsing is handled within the image and does not have to use 
> the Unix convention. I wouldn't recommend it because Squeak Image runs 
> on multiple platforms. The convention would be to check if the first arg 
> is a registered command word (e.g. eval st) or a chunk file (*.st) and 
> then let the command/script parse the rest of the arguments.
> 
> Regards .. Subbu
> 
-------------- next part --------------
#!/bin/sh
# dtl Wed May 20 19:49:25 EDT 2015
# Mon Apr 10 19:18:47 EDT 2017
#
# VM run utility script, typicially installed as /usr/local/bin/run
# usage: run <myimage>
#
# Select a VM and run an image based on the image format number
#
# Assume that /usr/local/bin/squeak runs the traditional VM for 32-bit
# and 64-bit images in the traditional image formats. Assume that
# /usr/local/bin/cog runs Cog, /usr/local/bin/spur runs the VM for 32-bit
# Spur images, and /usr/local/bin/spur64 runs the VM for 64-bit Spur
# images.
#
# Use ckformat to determine image requirements. See package ImageFormat
# in the SqueakSource VMMaker repository. The executable is distributed
# with the standard interpreter VM. To generate C source for the ckformat
# utility, evaluate:
#    "ImageFormat createCkStatusProgram"
#

# VMs look for this default name if an image has not been
# specified. Use the same default for this script.
DEFAULT_IMAGENAME="squeak.image"

# Scripts for running various interpreters
INTERP_SCRIPT="squeak"       # Context VM for 32 and 64 bit images
COG_SCRIPT="cog"             # Cog VM
SPUR_SCRIPT="spur"           # Spur VM for 32-bit Spur image
SPUR64_SCRIPT="spur64"       # Spur VM for 64-bit Spur image

# Assume scripts are in the same directory, e.g. /usr/local/bin
BIN=`dirname "$0"`

# The ckformat utility is distributed with interpreter VM builds.
# Find it in the lib directory for the interpreter VM.
CKFORMAT=`squeak -version | grep 'plugin path' | sed 's/^.*default: //' | sed 's/]$//'`ckformat

# Paths to the run scripts
INTERP="$BIN/$INTERP_SCRIPT" # Context interpreter VM
COG="$BIN/$COG_SCRIPT"       # Cog VM for 32-bit images with closure support
SPUR="$BIN/$SPUR_SCRIPT"     # Spur VM for Spur 32-bit image format 6521
SPUR64="$BIN/$SPUR64_SCRIPT" # Spur VM for Spur 64-bit image format 68109

for arg in $*
do
  case ${arg} in
  -*) #ignore
    ;;
  *) # either and option argument or the image name
    if test -f ${arg}
    then
      NUM=`${CKFORMAT} ${arg} 2>/dev/null`
      if test $? -eq 0
      then
        IMAGENAME=${arg}
        break
      fi
    else
      if test -f ${arg}.image
      then
        NUM=`${CKFORMAT} ${arg}.image 2>/dev/null`
        if test $? -eq 0
        then
          IMAGENAME=${arg}.image
          break
        fi
      fi
    fi
    ;;
  esac
done

# if no image name specified on command line, try the default
if test ! ${IMAGENAME}
then
  if test -f ${DEFAULT_IMAGENAME}
  then
    IMAGENAME=${DEFAULT_IMAGENAME}
    NUM=`${CKFORMAT} ${IMAGENAME} 2>/dev/null`
    if test $? -ne 0
    then
      echo image format ${NUM} not recognized for ${IMAGENAME}
      exit 1
    fi
  else
    echo `basename $0` $@: image file not found
    exit 1
  fi
fi

case $NUM in
  6502)
    VM=$INTERP
    ;;
  6504 | 6505)
    VM=$COG
    ;;
  6521)
    VM=$SPUR
    ;;
  68000 | 68002 | 68003)
    VM=$INTERP
    ;;
  68019)
    VM=$SPUR64 # early spur 64
    ;;
  68021)
    VM=$SPUR64
    ;;
  *)  echo image format ${NUM} not recognized for ${IMAGENAME}
    exit -1;;
esac

# Use standard VM as default if preferred VM not present
if test ! -x ${VM}
then
  echo ${VM} not found, using ${INTERP}
  VM="${INTERP}"
fi

### echo running ${IMAGENAME} with image format $NUM using $VM
exec ${VM} "$@"



More information about the Squeak-dev mailing list