aboutsummaryrefslogtreecommitdiffstats
path: root/src/_port
blob: 0f12e15bfa95dcb5ad180c45757fb83b82522454 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
#compdef port
# ------------------------------------------------------------------------------
# Description
# -----------
#
#  Completion script for MacPorts 2.12.1 (https://www.macports.org/).
#
# ------------------------------------------------------------------------------
# Authors
# -------
#
#  * Matt Cable <wozz@wookie.net>
#  * Sorin Ionescu <sorin.ionescu@gmail.com>
#  * Aljaž Srebrnič <a2piratesoft@gmail.com>
# -----------------------------------------------------------------------------
# License
# -------
#
# Copyright (c) 2016, Matt Cable, Sorin Ionescu, Aljaž Srebrnič
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the <organization> nor the
#       names of its contributors may be used to endorse or promote products
#       derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# ------------------------------------------------------------------------------

# global variable
#_port_available_packages
#_port_installed_packages

_port() {
  typeset -A opt_args
  local context state line
  local curcontext="$curcontext"
  local ret=1

  local port_prefix=${commands[port]%/bin/port}

  _arguments -s -C \
    '-v[Verbose mode (generate verbose messages)]' \
    '-d[Debug mode (generate debugging messages, implies -v)]' \
    '-q[Quiet mode (suppress messages)]' \
    '-N[Non-interactive mode]' \
    "-n[Don't follow dependencies in upgrade (affects upgrade and install)]" \
    "-R[Also upgrade dependents (only affects upgrade) ]" \
    '-u[Uninstall inactive ports when upgrading and uninstalling]' \
    '-y[Perform a dry run]' \
    '-s[Source-only mode (build and install from source)]' \
    '-b[Binary-only mode (build and install from binary archives)]' \
    '-c[Autoclean mode (execute clean after install)]' \
    "-k[Keep mode (don't autoclean after install)]" \
    '-p[Despite any errors encountered, proceed to process multiple ports and commands]' \
    '-o[Honor state files even if the Portfile has been modified since]' \
    '-t[Enable trace mode debug facilities on platforms that support it]' \
    '-f[Force mode, ignore state file]' \
    '-D[Specify portdir]:dir:_files -/' \
    '-F[Read and process the file of commands specified by the argument]:file:_files' \
    "1:Port actions:_port_actions" \
    '*::arg:->args' \
    && ret=0

  case "$state" in
    (args)
      local subcmd=$words[1]
      local cache_policy
      zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
      zstyle ":completion:${curcontext}:" cache-policy ${cache_policy:-_port_caching_policy}

      local -a log_phases=('fetch' 'checksum' 'extract' 'patch' 'configure' 'build' 'destroot')
      local -a no_portname_commands=(
        'help' 'diagnose' 'migrate' 'outdated' 'platform' 'provides' 'reclaim' 'restore'
        'rev-upgrade' 'search' 'select' 'selfupdate' 'snapshot' 'sync' 'usage'
      )
      local -a show_installed_package_commands=(
        uninstall upgrade
        activate deactivate
        dependents rdependents
        setrequested unsetrequested setunrequested
        space location contents
      )

      local -a options=()
      case $subcmd in
        (activate|deactivate)
          options+=('--no-exec[Do not execute any stored pre- or post-uninstall procedures]')
          ;;
        (archivefetch)
          options+=('-p[Proceed even if a port fails to fetch]')
          ;;
        (fetch|checksum|extract|patch|configure|build|destroot|test)
          options+=('--no-mirrors[Only fetch files from URLs in master_sites]')
          ;;
        (bump)
          options+=('--patch[Create a Portfile.patch file instead of directly overwriting the Portfile]')
          ;;
        (clean)
          options+=(
            '--archive[Remove partially downloaded binary archives]'
            '--dist[Delete source code archives, the so-called distfiles]'
            '--logs[Delete log files]'
            '--work[Delete the work directory of a port]'
            '--all[Remove all temporary files]'
          )
          ;;
        (contents)
          options+=(
            "--size[Enable printing a human-readable representation of the files' size]"
            '--units[Used in conjunction with --size to choose the unit in which the size is given]:units:_port_units'
          )
          ;;
        (deps|rdeps)
          options+=(
            '--index[Do not read Portfiles, but instead rely solely on the PortIndex information]'
            '--no-build[Exclude dependencies only required at build time]'
            '--no-test[Exclude test dependencies]'
          )

          if [[ $subcmd == "rdeps" ]]; then
            options+=('--full[Display all branches of the dependency tree instead of listing each dependency only once]')
          fi
          ;;
        (diagnose)
          options+=('--quiet[Only display warnings or errors]')
          ;;
        (edit)
          options+=('--editor[Use the specified editor]:editor')
          ;;
        (help|usage)
          options+=('1:action:_port_actions')
          ;;
        (info)
          options+=(
            '--index[Do not read the Portfile, but rely solely on the port index information]'
            '--line[Print a single line for each port]'
            '--pretty[Format the output in a convenient, human-readable fashion]'
            '(--category --categories)'{--category,--categories}'[List the categories of a port]'
            '--conflicts[List other ports that cannot be activate at the same time as the given port]'
            '--depends_fetch[List the fetch dependencies of a port]'
            '--depends_extract[List the extract dependencies of a port]'
            '--depends_build[List the build dependencies of a port]'
            '--depends_lib[List the lib dependencies of a port]'
            '--depends_run[List the run dependencies of a port]'
            '--depends[List the all dependencies of a port]'
            '(--description --long_description)--description[Print the short description of a port]'
            '(--description --long_description)--long_description[Print the long description of a port]'
            '--epoch[List the epoch components of a MacPorts]'
            '--version[List the version components of a MacPorts]'
            '--revision[List the revision components of a MacPorts]'
            '--fullname[Print name and the full MacPorts version tuple]'
            '--heading[Like --fullname but including the categories]'
            '--homepage[List the homepage of a port]'
            '--license[Print the license that applies to the source code of a port]'
            '(--maintainer --maintainers)'{--maintainer,--maintainers}"[List the email address(es) of a port's maintainer(s)]"
            '--name[Print the name of a port]'
            '--pathfiles[List the patches that will be applied to the port]'
            '(--platform --platforms)'{--platform,--platforms}'[List the platforms supported by a port]'
            "--portdir[Print the path to a port's directory]"
            '--replaced_by[List the name of the port that replaces a port]'
            "--subports[Print a list of subports defined by this port's Portfile]"
            '(--variant --variants)'{--variant,--variants}'[List the variants defined by a port by name]'
          )
          ;;
        (install)
          options+=(
            '--allow-failing[Attempt installation even if the specified port is known to fail]'
            '--no-replace[Attempt to install specified port even if it is replaced by another port]'
            '--no-rev-upgrade[Do not run rev-upgrade after installation]'
            '--unrequested[Do not mark the installed ports as requested]'
          )
          ;;
        (lint)
          options+=('--nitpick[Enable additional checks that are mostly whitespace-related and best practices]')
          ;;
        (log)
          options+=(
            '--level[Log level]:level:(error warn msg info debug)'
            '--phase[Only print messages that were generated in the given installation phase]:phase:($log_phases)'
          )
          ;;
        (migrate)
          options+=(
            '--all[Migrate all ports including unrequested ones]'
            '--continue[Continue with migration of ports]'
          )
          ;;
        (mirror)
          options+=('--new[Delete the existing database of mirrored files and re-create it from scratch]')
          ;;
        (provides)
          options+=('*::file:_files')
          ;;
        (reclaim)
          options+=(
            '--keep-build-deps[Consider build-time dependency ports to be considered needed]'
            '(--enable-reminders --disable-reminders)--enable-reminders[Enable regular reminders to run "port reclaim"]'
            '(--enable-reminders --disable-reminders)--disable-reminders[Disable reminders to run "port reclaim"]'
          )
          ;;
        (restore)
          options+=(
            '--snapshot-id[Restore the snapshot with the specified ID]:id:_port_snapshot_ids'
            '--last[Restore the last created snapshot]'
            '--all[Restore all ports in the snapshot including unrequested ones]'
          )
          ;;
        (rev-upgrade)
          options+=('--id-loadcmd-check[Check the ID load command in each library installed by MacPorts]')
          ;;
        (search)
          options+=(
            '--case-sensitive[Do not ignore case when searching for the given keyword]'
            '(--exact --glob --regex)--exact[Search for the given string exactly]'
            '(--exact --glob --regex)--glob[Treat the keyword(s) as wildcard]'
            '(--exact --glob --regex)--regex[Treat the given string as a Tcl regular expression]'
            '--line[Print one match per line]'
            '(--category --categories)'{--category,--categories}'[Search the category]'
            '--depends_fetch[Search the fetch dependencies of a port]'
            '--depends_extract[Search the extract dependencies of a port]'
            '--depends_build[Search the build dependencies of a port]'
            '--depends_lib[Search the lib dependencies of a port]'
            '--depends_run[Search the run dependencies of a port]'
            '--depends[Search the all dependencies of a port]'
            '(--description --long_description)--description[Test the search string against the description]'
            '(--description --long_description)--long_description[Test the search string against the long description]'
            '--homepage[Search for the keyword(s) in the homepage property]'
            '(--maintainer --maintainers)'{--maintainer,--maintainers}"[Search for maintainers]"
            '--name[Search in ports name]'
            "--portdir[Test the search string against the path of the directory that contains the port]"
            '(--variant --variants)'{--variant,--variants}'[Search for variant names]'
          )
          ;;
        (select)
          options+=(
            '--summary[Display summary of selected options]'
            '--list[List available versions for the group]'
            '--set[Select the given version for the group]'
            '--show[Show which version is currently selected for the group (default if none given)]'
            '1:group:_port_select_groups'
            '2:variant:_port_select_variants'
          )
          ;;
        (selfupdate)
          options+=(
            '--no-sync[Only check for updates and install if available]'
            '--migrate[Rebuild even if no new version is available]'
            '--rsync[Use the older rsync method for downloading the new version of MacPorts]'
          )
          ;;
        (snapshot)
          options+=(
            '--create[Create a new snapshot that records the current active ports]'
            '--note[Label with the given note when creating a snapshot]:note'
            '--list[Display a list of all snapshots that currently exist]'
            '--diff[Display the differences between the given snapshot ID and currently installed ports]:id:_port_snapshot_ids'
            '--all[Consider all ports when displaying diffs]'
            '--delete[Delete the snapshot with the given ID number]:id:_port_snapshot_ids'
            '--export[Generate a JSON representation of the snapshot with the given ID number]:id:_port_snapshot_ids'
            '--import[Create a new snapshot from the information in the given file]:file:_files'
            '(- *)--help[Display brief usage information]'
          )
          ;;
        (space)
          options+=(
            '--total[Only print the total amount of space used by all given ports]'
            '--units[Choose the unit in which the size is given]:unit:_port_units'
          )
          ;;
        (uninstall)
          options+=(
            '--follow-dependents[Also uninstall all ports recursively depending directly or indirectly]'
            '--follow-dependencies[Also recursively uninstall all ports that the given port depends on]'
            '--no-exec[Do not execute any stored pre- or post-uninstall procedures]'
          )
          ;;
        (upgrade)
          options+=(
            '--enforce-variants[Upgrade all given ports and their dependencies]'
            '--force[Ignore circumstances that would normally cause ports to be skipped]'
            '--no-replace[Do not automatically install ports that replace a new-obsolete port you have installed]'
            '--no-rev-upgrade[Do not run rev-upgrade after upgrading]'
          )
          ;;
        (variants)
          options+=('--index[Do not read the Portfile]')
          ;;
      esac

      if (( $no_portname_commands[(Ie)$subcmd] )); then
        _arguments \
          $options[@] \
          && ret=0
      else
        local -a pseudo_port_names=(
          all current active inactive actinact installed uninstalled outdated
          obsolete requested unrequested leaves rleaves
        )

        local -a selectors=(
          'variants:' 'variant:' 'description:' 'depends:'
          'depends_lib:' 'depends_run:' 'depends_build:' 'depends_fetch:' 'depends_extract:'
          'portdir:' 'homepage:' 'epoch:' 'platforms:' 'platform:' 'name:' 'long_description:'
          'maintainers:' 'maintainer:' 'categories:' 'category:' 'version:' 'revision:' 'license:'
          'depof:' 'rdepof:' 'rdepends:' 'dependentof:' 'rdependentof:'
        )

        if (( $show_installed_package_commands[(Ie)$subcmd] )); then
          _port_update_cache "installed"

          _arguments \
            $options[@] \
            '1: :_port_installed_ports' \
            '*: :_port_options' \
            && ret=0
        else
          _port_update_cache "all"

          _arguments \
            $options[@] \
            '1: :_port_available_ports' \
            '*: :_port_options' \
            && ret=0
        fi
      fi

      ;;
  esac

  return ret
}

(( $+functions[_port_actions] )) ||
_port_actions() {
  local -a actions=(
    'activate:Activate the given ports'
    'archive:Archive the given ports, i.e. install the port image but do not activate'
    'archivefetch:Fetch archive for the given ports'
    'build:Build the given ports'
    'bump:Update the outdated checksums of a Portfile'
    'cat:Writes the Portfiles of the given ports to stdout'
    'checksum:Compares the checksums for the downloaded files of the given ports'
    'clean:Removes files associated with the given ports'
    'configure:Configure the given ports'
    'contents:Returns a list of files installed by given ports'
    'deactivate:Deactivates the given ports'
    'dependents:Returns a list of installed dependents for each of the given ports'
    'deps:Display a dependency listing for the given ports'
    'destroot:Destroot the given ports'
    'diagnose:Detects common issues'
    'dir:Returns the directories of the given ports'
    'distcheck:Checks if the given ports can be fetched from all of its master_sites'
    'distfiles:Returns a list of distfiles for the given port'
    'dmg:Creates a dmg for each of the given ports'
    'echo:Returns the list of ports the argument expands to'
    'edit:Edit given ports'
    'extract:Extract the downloaded files of the given ports'
    'fetch:Downloaded distfiles for the given ports'
    'file:Returns the path to the Portfile for each of the given ports'
    'gohome:Opens the homepages of the given ports in your browser'
    'help:Displays short help texts for the given actions'
    'info:Returns information about the given ports '
    'install:Installs the given ports'
    'installed:List installed versions of the given port, or all installed ports if no port is given'
    'lint:Checks if the Portfile is lint-free for each of the given ports'
    'list:List the available version for each of the given ports'
    'livecheck:Checks if a new version of the software is available'
    'load:Interface to launchctl(1) for ports providing startup items'
    'location:Returns the install location for each of the given ports'
    'log:Shows main log for given ports'
    'logfile:Returns the log file path for each of the given ports'
    'mdmg:Creates a dmg containing an mpkg for each of the given ports and their dependencies'
    'migrate:Update MacPorts for a new platform'
    'mirror:Fetches distfiles for the given ports'
    'mpkg:Creates an mpkg for each of the given ports and their dependencies'
    'notes:Displays informational notes for each of the given ports'
    'outdated:Returns a list of outdated ports'
    'patch:Applies patches to each of the given ports'
    'pkg:Creates a pkg for each of the given ports'
    'platform:Returns the current platform that port is running on'
    'provides:Return which port provides each of the files given'
    'rdependents:Recursive version of dependents'
    'rdeps:Display a recursive dependency listing for the given ports'
    'reclaim:Reclaims disk space'
    'reload:Restart daemon'
    'restore:Restore snapshots of installed ports'
    'rev-upgrade:Scan for broken binaries in the installed ports and rebuild them as needed'
    'search:Search for a port'
    'select:Select between multiple versions of a versioned port'
    'selfupdate:Upgrade MacPorts itself and run the sync target'
    'setrequested:Marks each of the given ports as requested'
    'setunrequested:Marks each of the given ports as unrequested'
    'snapshot:Create and manage snapshots of installed ports'
    'space:Show the disk space used by the given ports'
    'sync:Synchronize the set of Portfiles'
    'test:Run tests on each of the given ports'
    'unarchive:Unarchive the destroot of the given ports from installed images'
    'uninstall:Uninstall the given ports'
    'unload:Interface to launchctl(1) for ports providing startup items'
    'unsetrequested:Marks each of the given ports as unrequested'
    'upgrade:Upgrades the given ports to the latest version'
    'url:Returns the URL for each of the given ports'
    'usage:Returns basic usage of the port command'
    'variants:Returns a list of variants provided by the given ports, with descriptions if present'
    'version:Returns the version of MacPorts'
    'work:Returns the path to the work directory for each of the given ports'
  )

  _describe -t actions 'actions' actions
}

(( $+functions[_port_options] )) ||
_port_options() {
  local current_arg=$words[CURRENT]

  # complete variants
  if [[ $current_arg == +* || $current_arg == -* ]]; then
    IPREFIX=$current_arg[1]
    PREFIX=$current_arg[2,-1]
    _port_variants $words[2]
  fi
}

(( $+functions[_port_available_ports] )) ||
_port_available_ports() {
  _alternative \
    'ports:Available ports:($_port_available_packages)' \
    'pseudo-common:Common Pseudo-portnames:($pseudo_port_names)' \
    'selectors:Pseudo portname selectors:($selectors)'
}

(( $+functions[_port_installed_ports] )) ||
_port_installed_ports() {
  _alternative \
    "ports:Installed ports:($_port_installed_packages)" \
    "pseudo-common:Common Pseudo-portnames:($pseudo_port_names)" \
    "selectors:Pseudo portname selectors:($selectors)"
}

(( $+functions[_port_caching_policy] )) ||
_port_caching_policy() {
  local reg_time comp_time check_file

  zmodload -F zsh/stat b:zstat 2> /dev/null
  case "${1##*/}" in
    (PORT_INSTALLED_PACKAGES)
      check_file=$port_prefix/var/macports/registry/registry.db
      ;;
    (PORT_AVAILABLE_PACKAGES)
      check_file=${$(port dir MacPorts)%/*/*}/PortIndex
      ;;
  esac

  reg_time=$(zstat +mtime $check_file)
  comp_time=$(zstat +mtime $1)
  return $(( reg_time < comp_time ))
}

(( $+functions[_port_update_cache] )) ||
_port_update_cache() {
  local cache_type=$1

  case "$cache_type" in
    (all)
      # Cache the list of all ports.
      if ( [[ ${+_port_available_packages} -eq 0 ]] || _cache_invalid PORT_AVAILABLE_PACKAGES ) &&
           ! _retrieve_cache PORT_AVAILABLE_PACKAGES;
      then
        _port_available_packages=( $(_call_program path-all "port -q echo all") )
        _store_cache PORT_AVAILABLE_PACKAGES _port_available_packages
      fi
      ;;
    (installed)
      if ( [[ ${+_port_installed_packages} -eq 0 ]] || _cache_invalid PORT_INSTALLED_PACKAGES ) &&
           ! _retrieve_cache PORT_INSTALLED_PACKAGES;
      then
        _port_installed_packages=( $(_call_program path-all "port -q echo installed") )
        _store_cache PORT_INSTALLED_PACKAGES _port_installed_packages
      fi
      ;;
  esac
}

(( $+functions[_port_select_groups] )) ||
_port_select_groups() {
  local -a groups=($port_prefix/etc/select/*(N:t))
  _describe "Port select groups" groups
}

(( $+functions[_port_select_variants] )) ||
_port_select_variants() {
  local group=$words[2]
  local -a variants=("${(f)$(port select --list $group | awk '/^[ \t]+/{print $1}')}")
  _describe "Port select group $words[4] variants" variants
}

(( $+functions[_port_snapshot_ids] )) ||
_port_snapshot_ids() {
  local -a snapshot_ids=()
  if (( $+commands[perl] )); then
    local perl_expr='m{^\s+(\d+)\s+(.*)$} and printf "%s:%s\n", $1, $2'
    snapshot_ids=("${(f)$(port snapshot --list | perl -wln -e $perl_expr)}")
  else
    local awk_expr='NR > 2 { printf("%s:%s %s\n", $1, $2, $3) }'
    snapshot_ids=("${(f)$(port snapshot --list | awk $awk_expr)}")
  fi

  _describe "Port snapshot IDs" snapshot_ids
}

(( $+functions[_port_variants] )) ||
_port_variants() {
  local name=$1
  if (( $+commands[perl] )); then
    local -a variants=($(port variants $name | perl -wln -e 'm{^(?:\s+|\[\+\])([^:]+):} and print $1'))
    if [[ ${#variants} != 0 ]]; then
      _values 'variant' $variants
    fi
  fi
}

(( $+functions[_port_units] )) ||
_port_units() {
  local -a units=(
    "B[List sizes in bytes]"
    {K,Ki,KiB}"[List sizes in KiB, 1024 bytes]"
    {Mi,MiB}'[List sizes in MiB, 1024 * 1024 bytes]'
    {Gi,GiB}'[List sizes in GiB, 1024 * 1024 * 1024 bytes]'
    {k,kB}'[List sizes in kB, 1000 bytes]'
    {M,MB}'[List sizes in kB, 1000 * 1000 bytes]'
    {G,GB}'[List sizes in kB, 1000 * 1000 * 1000 bytes]'
  )
  _values 'unit' $units
}

_port "$@"

# Local Variables:
# mode: Shell-Script
# sh-indentation: 2
# indent-tabs-mode: nil
# sh-basic-offset: 2
# End:
# vim: ft=zsh sw=2 ts=2 et