[scripts][fuzzing] Fix '-d' option.

This CL allows options to appear anywhere in a command, instead of
immediately after the command (which wasn't what the help documented!).
It also now uses the result of `fx set-device` if that has been run and
`-d` is not supplied.

Bug: SEC-285
Test: fx set core.x64 --with //src/fuzzing:tests
      fx run-host-tests fuzzing_host_test
Change-Id: I7aa11962394d4d7165cd23d33fa3f6e31e084fb3
diff --git a/scripts/fuzzing/lib/device.py b/scripts/fuzzing/lib/device.py
index ebf3a3c..f0e1d87 100644
--- a/scripts/fuzzing/lib/device.py
+++ b/scripts/fuzzing/lib/device.py
@@ -28,12 +28,16 @@
   def from_args(cls, host, args):
     """Constructs a Device from command line arguments."""
     netaddr_cmd = ['netaddr', '--fuchsia', '--nowait']
+    default_device = '{}.device'.format(host.build_dir)
     if args.device:
       netaddr_cmd.append(args.device)
+    elif os.path.exists(default_device):
+      with open(default_device) as f:
+        netaddr_cmd.append(f.read().strip())
     try:
       netaddr = host.zircon_tool(netaddr_cmd)
     except subprocess.CalledProcessError:
-      raise RuntimeError('Unable to find device')
+      raise RuntimeError('Unable to find device; try `fx set-device`.')
     device = cls(host, netaddr)
     if not host.build_dir:
       raise Host.ConfigError('Unable to find SSH configuration.')
diff --git a/tools/devshell/contrib/fuzz b/tools/devshell/contrib/fuzz
index 2ab7201..cc8b9e1 100755
--- a/tools/devshell/contrib/fuzz
+++ b/tools/devshell/contrib/fuzz
@@ -8,7 +8,7 @@
 ##
 ## Usage: fx fuzz [options] [command] [command-arguments]
 ##
-## Options (must be first):
+## Options:
 ##   -d, --device   <name>   Connect to device using Fuchsia link-local name.
 ##                           Must be specified if multiple devices are present.
 ##   -f, --foreground        Run in the foreground (default is background).
@@ -61,42 +61,75 @@
 
 FUZZING_DIR=${FUCHSIA_DIR}/scripts/fuzzing
 
-cmd=${1:-help}
-shift
+cmd=
+while [[ -n "$1" ]] ; do
+  case "$1" in
+    -h|--help)
+      cmd="help"
+      ;;
+    -d|--device|-o|--output|-s|--staging)
+      if [[ -z "$2" ]] ; then
+        echo "Missing argument to $1"
+        cmd="help"
+      else
+        opts="$opts $1 $2"
+      fi
+      shift
+      ;;
+    -f|--foreground|-n|--no-cipd)
+      opts="$opts $1"
+      ;;
+    -*)
+      echo "Unknown option: $1"
+      cmd="help"
+      ;;
+    *)
+      if [[ -z "$cmd" ]] ; then
+        cmd="$1"
+      else
+        args="$args $1"
+      fi
+      ;;
+  esac
+  shift
+done
+
+
 case "${cmd}" in
   help)
     fx-command-help
     ;;
   list)
-    python ${FUZZING_DIR}/list_fuzzers.py "$@"
+    python ${FUZZING_DIR}/list_fuzzers.py "$opts $args"
     ;;
   corpus)
-    python ${FUZZING_DIR}/list_corpora.py "$@"
+    python ${FUZZING_DIR}/list_corpora.py "$opts $args"
     ;;
   fetch)
-    python ${FUZZING_DIR}/fetch_corpus.py "$@"
+    python ${FUZZING_DIR}/fetch_corpus.py "$opts $args"
     ;;
   start)
-    python ${FUZZING_DIR}/start_fuzzer.py "$@" &
+    python ${FUZZING_DIR}/start_fuzzer.py "$opts $args" &
     ;;
   check)
-    python ${FUZZING_DIR}/check_fuzzer.py "$@"
+    python ${FUZZING_DIR}/check_fuzzer.py "$opts $args"
     ;;
   stop)
-    python ${FUZZING_DIR}/stop_fuzzer.py "$@"
+    python ${FUZZING_DIR}/stop_fuzzer.py "$opts $args"
     ;;
   repro)
-    python ${FUZZING_DIR}/repro_units.py "$@"
+    python ${FUZZING_DIR}/repro_units.py "$opts $args"
     ;;
   merge)
-    python ${FUZZING_DIR}/merge_corpus.py "$@"
+    python ${FUZZING_DIR}/merge_corpus.py "$opts $args"
     ;;
   store)
-    python ${FUZZING_DIR}/store_corpus.py "$@"
+    python ${FUZZING_DIR}/store_corpus.py "$opts $args"
     ;;
   *)
-    if python ${FUZZING_DIR}/list_fuzzers.py "${cmd}" ; then
-      python ${FUZZING_DIR}/start_fuzzer.py "${cmd}" "$@" &
+    name="$cmd"
+    if python ${FUZZING_DIR}/list_fuzzers.py "$opts $name" ; then
+      python ${FUZZING_DIR}/start_fuzzer.py "$opts $name $args" &
     else
       fx-command-help
     fi