Skip to content

Commit

Permalink
main: Improve command-line handling and usage string
Browse files Browse the repository at this point in the history
To determine program name from argv[0]/argv[1] remove everything after
the first '-' or '.' character. This allows names like snabbnfv,
snabbnfv-1.0, snabbnfv-lukes-turbo-charged-version, snabbnfv.linux,
and so on.

Make the usage printout for 'snabb' and 'snabb -h' and 'snabb --help' better:

    Usage: ./snabb <program> ...

    This snabb executable has the following programs built in:
      packetblaster
      snabbmark
      snabbnfv
      snsh

    For detailed usage of any program run:
      snabb <program> --help

    If you rename (or copy or symlink) this executable with one of
    the names above then that program will be chosen automatically.

The program list is determined automatically by the Makefile.
  • Loading branch information
lukego committed May 12, 2015
1 parent b69ad9c commit cb5db6c
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 22 deletions.
8 changes: 7 additions & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,19 @@ $(RMOBJS): %: %.src
$(E) "MARKDOWN $@"
$(Q) scripts/process-markdown $< > $@

$(INCOBJ): obj/%_inc.o: %.inc Makefile | $(OBJDIR)
$(INCOBJ): obj/%_inc.o: %.inc Makefile program/programs.inc | $(OBJDIR)
$(E) "INC $@"
@(echo -n "return [=============["; \
cat $<; \
echo "]=============]") > $(basename $@).luainc
$(Q) luajit -bg -n $(subst /,.,$*)_inc $(basename $@).luainc $@

# Create list of programs that exist
program/programs.inc:
@ls -1d program/*/ | xargs basename -a > $@

.FORCE: program/programs.inc

# extra/ third party bits and pieces
obj/strict.o: extra/strict.lua | $(OBJDIR)
$(E) "LUA $@"
Expand Down
62 changes: 41 additions & 21 deletions src/core/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,43 +33,63 @@ function main ()
zone("startup")
require "lib.lua.strict"
initialize()
local program, args = parse_command_line()
parameters = args
if not program then
print("Usage: snabb <PROGRAM> [ARGS]...")
os.exit(1)
local program
local args = parse_command_line()
if programname(args[1]) == 'snabb' then
-- Print usage when no arguments or -h/--help
if #args == 1 or args[2] == '-h' or args[2] == '--help' then
usage()
os.exit(1)
else
-- Strip 'snabb' and use next argument as program name
table.remove(args, 1)
end
end
local program = table.remove(args, 1)
if not lib.have_module(modulename(program)) then
print(programname(program) .. ": unrecognized program name")
print("unsupported program: "..programname(program))
print()
print("Rename this executable (cp, mv, ln) to choose a supported program:")
print(" snabb "..(require("program.programs_inc"):gsub("\n", " ")))
os.exit(1)
else
require(modulename(program)).run(args)
end
require(modulename(program)).run(parameters)
end

-- programname("nfv-sync-master.2.0") => "nfv-sync-master"
function usage ()
print("Usage: "..ffi.string(C.argv[0]).." <program> ...")
local programs = require("program.programs_inc"):gsub("[a-z]+", " %1")
print()
print("This snabb executable has the following programs built in:")
print(programs)
print("For detailed usage of any program run:")
print(" snabb <program> --help")
print()
print("If you rename (or copy or symlink) this executable with one of")
print("the names above then that program will be chosen automatically.")
end


-- programname("snabbnfv-1.0") => "snabbnfv"
function programname (program)
return string.match(program, "([^/]+)$")
program = program:gsub("^.*/", "") -- /bin/snabb-1.0 => snabb-1.0
program = program:gsub("[-.].*$", "") -- snabb-1.0 => snabb
return program
end
-- modulename("nfv-sync-master.2.0") => "program.nfv.nfv_sync_master")
function modulename (program)
program = programname(string.gsub(program, "-", "_"))
program = programname(program)
return ("program.%s.%s"):format(program, program)
end

-- Return two values: program and parameters.
--
-- Program is the name of the program to run. For example 'snsh' or
-- 'packetblaster'.
-- Return all command-line paramters (argv) in an array.
function parse_command_line ()
local commandline = {}
local array = {}
for i = 0, C.argc - 1 do
table.insert(commandline, ffi.string(C.argv[i]))
end
local program = table.remove(commandline, 1)
if programname(program) == 'snabb' then
program = table.remove(commandline, 1)
table.insert(array, ffi.string(C.argv[i]))
end
return program, commandline
return array
end

function exit (status)
Expand Down

0 comments on commit cb5db6c

Please sign in to comment.