zsh-workers
 help / color / mirror / code / Atom feed
cbada7de950376410444fddb9fb42703c7dfc5f1 blob 42625 bytes (raw)

   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
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
 
------------------------------
GUIDELINES FOR ZSH DEVELOPMENT
------------------------------

Zsh is currently developed and maintained by the Zsh Development Group.
This development takes place by mailing list.  Check the META-FAQ for the
various zsh mailing lists and how to subscribe to them.  The development
is very open and anyone is welcomed and encouraged to join and contribute.
Because zsh is a very large package whose development can sometimes
be very rapid, we kindly ask that people observe a few guidelines when
contributing patches and feedback to the mailing list.  These guidelines
are very simple and hopefully should make for a more orderly development
of zsh.

Tools
-----

To develop (as opposed to just build) zsh, you'll need a few specialised
tools:

* GNU autoconf, version 2.50 or later.  This version contained
  significant enhancements and earlier versions will no
  longer work.

* GNU m4.  (Required by autoconf.)

* yodl.

* texi2html.

Patches
-------

* Send all patches to the mailing list rather than directly to me.

* Send only context diffs "diff -c oldfile newfile" or unified diffs
  "diff -u oldfile newfile".  They are much easier to read and
  understand while also allowing the patch program to patch more
  intelligently.  Please make sure the filenames in the diff header
  are relative to the top-level directory of the zsh distribution; for
  example, it should say "Src/init.c" rather than "init.c" or
  "zsh/Src/init.c".  Git-style naming of diffs is also acceptable.

* Please put only one bug fix or feature enhancement in a single patch and
  only one patch per mail message.  This helps me to multiplex the many
  (possibly conflicting) patches that I receive for zsh.  You shouldn't
  needlessly split patches, but send them in the smallest LOGICAL unit.

* If a patch depends on other patches, then please say so.  Also please
  mention what version of zsh this patch is for.

* Please test your patch and make sure it applies cleanly. It takes
  considerably more time to manually merge a patch into the baseline code.

* By convention, patches should be sent with a Subject: line starting with
  one of "PATCH:", "[PATCH]" or "[PATCH n/m]" (for a patch series).

Git Workflow
------------

Zsh has migrated from CVS to git for version control. Thus far, we have
avoided further changes to our workflow.

 * To allow changesets to be cross-referenced between the mailing list
   archives and version control history, commit messages should start with
   the mailing list sequence number. This number is generated by the list
   server and inserted as an X-Seq: header field in the e-mail.

 * An entry in the ChangeLog file should be added manually before pushing
   a commit to the master repository. Don't create a separate change for
   this: amend the existing commit in your local repository.

   Several developers use scripts to automate part or all of the ChangeLog
   workflow:

     Subject: helper script for making ChangeLog entries
     X-Seq: 33835, 33872, 34912
     http://www.zsh.org/mla/workers/2014/msg01622.html
     http://www.zsh.org/mla/workers/2014/msg01659.html
     -> https://github.com/ft/zsh-am
     http://www.zsh.org/mla/workers/2015/msg00836.html
     -> https://github.com/danielshahaf/zsh-dev

     Subject: Re: _git commit object name completion
     X-Seq: 35414
     http://www.zsh.org/mla/workers/2015/msg01338.html

 * Do not merge your private feature branches onto the master branch: a
   linear history without merge commits is simpler to follow (and to
   bisect).

Use of Git
----------

Micro Git Tutorial:

  % $VISUAL file1.c file2.c new-file3.c
  % git add new-file3.c
  % git commit -a
  % git pull --rebase
  % git push

 "git commit -a" automatically finds files which are tracked and have
 been modified, but doesn't pick up new files; "git add" adds a file to
 the index to be part of the next commit, and can be used for new files
 or for existing files (commit -a is a shortcut for the latter)

"git pull --rebase" ensures your local branch is up to date, needed
before pushing; the "--rebase" option means that any changes
in files also modified by you are handled by replaying your changes
onto the remote ones, which avoids any unnecessary merges in the
resulting history.

 "git push" assumes that you're on the master branch and the repository
 was created by cloning it from some place, with default options.

Using a Local Feature Branch:

  % git checkout -b feature_foo
  % $VISUAL path/to/files ...
  % git commit -a
  [ generate single patch for changes ]
  % git diff master
  [ do mailing-list stuff here ]
  [ Switch back to master: ]
  % git checkout master
  [ and get the most recent changes: ]
  % git pull
  [ make the branch content now be relative to *new* master tip ]
  % git checkout feature_foo
  % git rebase master
  [ then bring in your changes: ]
  % git checkout master
  % git merge --squash feature_foo
  % $VISUAL ChangeLog
  % git add ChangeLog
  % git commit --amend
  % git push
  [ cleanup ]
  % git branch -d feature_foo

  The above assumes you want all your changes on the feature branch to be
  seen as a single change publicly. The normal git way to generate patches
  is to use git format-patch which produces separate patches already
  prepared for e-mailing. If you want to keep changes separate, don't use
  the --squash option to git merge. In this case, it can be wise to use
  --ff-only which ensures that you don't get a merge commit by only doing
  the merge if the master can be trivially moved forward. An alternative is
  to use git cherry-pick to pick out individual changes.

Git further reading:
 * git help tutorial
 * git help tutorial-2
 * git help gitcore-tutorial
 * http://www-cs-students.stanford.edu/~blynn/gitmagic/

Testing
-------

* Because zsh has a huge number of different options and interacts with
  a wide range of human and artificial life, it is very difficult to
  test the shell thoroughly.  For this purpose, the Test subdirectory
  exists.  It consists of a driver script (ztst.zsh) and various test
  files (*.ztst) in a format which is described in B01cd.ztst, which acts
  as a template.  It is designed to make it easy to provide input to
  chunks of shell code and to test the corresponding standard output,
  error output and exit status.

* There is not much there yet, but please don't let that put you off adding
  tests for basic syntactic features, builtins, options etc. which you
  know to be flakey or to have had difficulties in the past.  Better
  support for testing job control and interactive features is expected
  to follow eventually.

* The directory is not part of the usual process of building and
  installation.  To run the tests, go to Test and `make check'.  Please
  report any errors with all the usual information about the zsh version
  and the system you are using.

C coding style
--------------

* The primary language is ANSI C as defined by the 1989 standard, but the
  code should always be compatible with late K&R era compilers ("The C
  Programming Language" 1st edition, plus "void" and "enum").  There are
  many hacks to avoid the need to actually restrict the code to K&R C --
  check out the configure tests -- but always bear the compatibility
  requirements in mind.  In particular, preprocessing directives must
  have the "#" unindented, and string pasting is not available.

* Conversely, there are preprocessor macros to provide safe access to some
  language features not present in pure ANSI C, such as variable-length
  arrays.  Always use the macros if you want to use these facilities.

* Avoid writing code that generates warnings under gcc with the default
  options set by the configure script.  For example, write
  "if ((foo = bar))" rather than "if (foo = bar)".

* Please try not using lines longer than 79 characters.

* The indent/brace style is Kernighan and Ritchie with 4 characters
  indentations (with leading tab characters replacing sequences of
  8 spaces).  This means that the opening brace is the last character
  in the line of the if/while/for/do statement and the closing brace
  has its own line:

      if (foo) {
	  do that
      }

* Put only one simple statement on a line.  The body of an if/while/for/do
  statement has its own line with 4 characters indentation even if there
  are no braces.

* Do not use space between the function name and the opening parenthesis.
  Use space after if/for/while.  Use space after type casts.

* Do not use (unsigned char) casts since some compilers do not handle
  them properly.  Use the provided STOUC(X) macro instead.

* If you use emacs 19.30 or newer you can put the following line to your
  ~/.emacs file to make these formatting rules the default:

    (add-hook 'c-mode-common-hook (function (lambda () (c-set-style "BSD"))))

* Function declarations must look like this:

  /**/
  int
  foo(char *s, char **p)
  {
      function body
  }

  There must be an empty line, a line with "/**/", a line with the
  type of the function, and finally the name of the function with typed
  arguments.  These lines must not be indented.  The script generating
  function prototypes and the ansi2knr program depend on this format.

* Variable declarations must similarly be preceded by a
  line containing only "/**/", for the prototype generation script.
  The declaration itself should be all on one line (except for multi-line
  initialisers).

* Preprocessor directives that affect the function/variable declarations must
  also be preceded by a "/**/" line, so that they get copied into the
  prototype lists.

* There are three levels of visibility for a function or variable.  It can
  be file-local, for which it must be marked with the keyword "static" at
  the front of the declaration.  It can be visible to other object files in
  the same module, for which it requires no extra keyword.  Or it can be
  made available to the entire program (including other dynamically loaded
  modules), for which it must be marked with the pseudo-keyword "mod_export"
  at the front of the declaration.  Symbols should have the least visibility
  possible.

* Leave a blank line between the declarations and statements in a compound
  statement, if both are present.  Use blank lines elsewhere to separate
  groups of statements in the interests of clarity.  There should never
  be two consecutive blank lines.

* Each .c file *must* #include the .mdh header for the module it is a
  part of and then its own .pro file (for local prototypes).  It may
  also #include other system headers.  It *must not* #include any other
  module's headers or any other .pro files.

* The repository includes a `.editorconfig' file with whitespace/indent
  control settings. Information about text editor plugins and this file
  can be found at <http://editorconfig.org/>.


Modules
-------

Modules have hierarchical names.  Name segments are separated by `/', and
each segment consists of alphanumerics plus `_'.  Relative names are never
used; the naming hierarchy is strictly for organisational convenience.

Each module is described by a file with a name ending in `.mdd' somewhere
under the Src directory.  This file is actually a shell script that will
sourced when zsh is built. To describe the module it can/should set the
following shell variables:

  - name            name of the module
  - link            `static', `dynamic' or `no', as described in INSTALL.
		    In addition, the value `either' is allowed in the .mdd
		    file, which will be converted by configure to `dynamic'
		    if that is available, else `static'.
		    May also be a command string, which will be run within
		    configure and whose output is used to set the value
		    of `link' in config.modules.  This allows a
		    system-specific choice of modules.  For example,
		    link='case $host in *-hpux*) echo dynamic; ;;
		                        *) echo no; ;; esac'
  - load            `yes' or `no': whether the shell should include hooks
		    for loading the module automatically as necessary.
		    (This corresponds to an `L' in xmods.conf in the
		    old mechanism.)
  - moddeps         modules on which this module depends (default none)
  - nozshdep        non-empty indicates no dependence on the `zsh/main'
                    pseudo-module
  - alwayslink      if non-empty, always link the module into the executable
  - autofeatures    features defined by the module for autoloading,
                    a space-separated list.  The syntax for features is as
                    for zmodload -F, e.g. b:mybin refers to the builtin
                    mybin.  This replaces the previous mechanism with
                    separate variables for builtins, conditions, math
                    functions and parameters.  Note the features are only
                    available in zsh's native mode, not in emulation modes.
  - autofeatures_emu As autofeatures, but the features so presented are
                    available in modes that are *not* zsh's native mode.
		    The variable autofeatures must also be present.
  - objects         .o files making up this module (*must* be defined)
  - proto           .syms files for this module (default generated from $objects)
  - headers         extra headers for this module (default none)
  - hdrdeps         extra headers on which the .mdh depends (default none)
  - otherincs       extra headers that are included indirectly (default none)

Be sure to put the values in quotes. For further enlightenment have a look
at the `mkmakemod.sh' script in the Src directory of the distribution.

Modules have to define six functions which will be called automatically
by the zsh core. The first one, named `setup_', should set up any data
needed in the module, at least any data other modules may be interested
in.

The next pair are `features_' and `enables_' and deal with enabling module
features.  Ensure you are familiar with the description of features under
`zmodload -F'.

The function features_ takes an argument `char ***featuresp'; *featuresp
is to be set to a NULL-terminated array containing a list of all the
features.  It should then return zero.  It may return one to indicate
features are not supported, but this is not recommended.  The function
featuresarray conveniently interrogates the module's feature structures
for all standard features; space is left for abstract features at the end
of the array and the names must be added by the module.  Note that heap
memory should be used for this (zhalloc, etc.) as memory for the features
array is not freed; note also the pointers for the abstract features are
not initialised so setting them is mandatory any time there are any
present.

A structure "struct features" should be used to contain all standard
features as well as the number of abstract features (those only understood
by the module itself).  See below.

enables_ takes an argument `int **enablesp'.  If *enablesp is NULL, it
should be set to an array of the same length as *featuresp without the
NULL, containing a 1 for every feature that is enabled and a zero for other
feature.  By default features are disabled.  If *enablesp is not NULL, its
values should be used to decide whether features are to be turned off.  It
should return status 0 for success, 1 on a failure to alter a feature.  The
function handlefeatures() conveniently handles all standard features
present in the module's features structure; abstract features must be
handled by the module (as with the features array, the area of the enables
array for abstract features is not even initialised by the main shell).  As
with `features_', any handling of the array by the module itself should take
into account that the array will not be freed and any allocation should
therefore be from heap memory.

The functions `features_' and `enables_' can be called at any point
after `setup_' has been called and before `cleanup_' is called.  In
particular they can be called before or after `boot_'.

The function named `boot_' should register function wrappers, hooks and
anything that will be visible to the user that is not handled by features_
and enables_ (so features should not be turned on here).  It will be called
after the `setup_'-function, and also after the initial set of features
have been set by calls to `features_' and `enables_'.

The function named `cleanup_', is called when the user tries to unload
a module and should de-register all features and hooks.  A call
to setfeatures with the final argument NULL will remove all standard
features present in the module's features structure.  Note that
`cleanup_' is called whenever `setup_' succeeded, so that `cleanup_'
must be prepared to handle any state resulting from a failed `boot_'
or initial call to `features_'.  Note also that a return code of 1
from `cleanup_' will result in the module not being unloaded, so
usually `cleanup_' will return 0 even if it has to handle an unclean
state; if it does return 1, it must be prepared to be called again
in a future attempt to unload.

The last function, `finish_' is called when the module is actually unloaded
and should finalize all the data initialized in the `setup_'-function.
However, `finish_' is called even if `setup_' failed, so it should
not rely on the module successfully being set up.
The state from `finish_' module is currently ignored; it is called
too late to prevent the module from being unloaded.
*Note* in addition to freeing memory, variables associated with allocated
memory should be set to NULL or to indicate arrays are empty, etc.  It
should not be assumed that the variables will automatically be zeroed if
the module is reloaded (though some configurations may do this).

In short, the `cleanup_'-function should undo what the `boot_'-function did
(together with handling any residual effects of `enables_'), but should
not rely on `boot_' having been successful, and the
`finish_'-function should undo what the `setup_'-function did, but
should not rely on `setup_' having been successful.

All of these functions should return zero if they succeeded and
non-zero otherwise.

Features
========

Builtins, conditions, parameters (variables) and math functions
are described as "features".  They should be made available to
the shell by declaring a `struct feature' for each module.
Below are descriptions of the individual features; first here
is generic information.

`struct feature' contains a pointer to the array that declares each
feature, followed by the number of entries in the array.  The pointer
can be NULL and the size zero for any feature that is not present in
the module.  For example, to register only builtins in zsh and thereby
make them visible to the user, the structure should contain
"bintab" where the array is declared as an array of struct builtin,
as discussed below:

  static struct feature module_features = {
    bintab, sizeof(bintab)/sizeof(*bintab),
    NULL, 0, /* declare any conditions here */
    NULL, 0, /* declare any parameters here */
    NULL, 0, /* declare any math functions here */
    0, /* number of abstract features */
  }

Within each individual table ("bintab", etc.), features should be listed
in ASCII order as no further sorting is performed by the shell when
features are listed.

Abstract features are handled by the module; the number present
in `struct features' is there to ensure the main shell allocated
space in the features and enables array in the standard
featuresarray() and handlefeatures() calls.  However, the inserting
of names in the features array and the getting and setting of
feature enables is left entirely to the module.  Note that abstract
features should not contain a colon (to avoid clashes with the
prefixes used in standard features).  It is recommended that
only alphanumerics, - and _ be used in the names of abstract
features, and - not be the first character (to avoid confusion
with disabling features) but this is not required by the main shell.

The features_ and enables_ functions for such a module will look
like:

  /**/
  int
  features_example(Module m, char ***features)
  {
     *features = featuresarray(m->nam, &module_features);
     /* fill in any abstract features in (*features) here */
     return 0;
  }
 
  /**/
  int
  enables_example(Module m, int **enables)
  {
    int ret;

    ret = handlefeatures(m->nam, &module_features, enables);
    /* handle any abstract features here */
    ...
    return ret;
  }

The functions shown take the name of the module, the set of features,


To de-register builtins, pass the features structure to
setfeatureenables with a NULL final value:

  /**/
  int
  cleanup_example(Module m)
  {
    setfeatureenables(m->nam, &module_features, NULL);
    ...
  }


Builtins
--------

Builtins are described in a table, for example:

  static struct builtin bintab[] = {
    BUILTIN("example", 0, bin_example, 0, -1, 0, "flags", NULL),
  };

Here `BUILTIN(...)' is a macro that simplifies the description. Its
arguments are:
  - the name of the builtin as a string
  - optional flags (see BINF_* in zsh.h)
  - the C-function implementing the builtin
  - the minimum number of arguments the builtin needs
  - the maximum number of arguments the builtin can handle or -1 if
    the builtin can get any number of arguments
  - an integer that is passed to the handler function and can be used
    to distinguish builtins if the same C-function is used to
    implement multiple builtins
  - the options the builtin accepts, given as a string containing the
    option characters (the above example makes the builtin accept the
    options `f', `l', `a', `g', and `s').  Passing NULL here disables
    all flag handling, i.e. even "--".  Each option letter may be
    followed by one of ":" (argument must follow), "::" (optional
    argument may follow), or ":%" (optional numeric argument).
  - and finally a optional string containing option characters that
    will always be reported as set when calling the C-function (this,
    too, can be used when using one C-function to implement multiple
    builtins)

The definition of the handler function looks like:

  /**/
  static int
  bin_example(char *nam, char **args, char *ops, int func)
  {
    ...
  }

The special comment /**/ is used by the zsh Makefile to generate the
`*.pro' files. The arguments of the function are the number under
which this function was invoked (the name of the builtin, but for
functions that implement more than one builtin this information is
needed). The second argument is the array of arguments *excluding* the 
options that were defined in the struct and which are handled by the
calling code. These options are given as the third argument. It is an
array of 256 characters in which the n'th element is non-zero if the
option with ASCII-value n was set (i.e. you can easily test if an
option was used by `if (ops['f'])' etc.). The last argument is the
integer value from the table (the sixth argument to `BUILTIN(...)').
The integer return value by the function is the value returned by the
builtin in shell level.

Conditions
----------

The definition of condition codes in modules is equally simple. First
we need a table with the descriptions:

  static struct conddef cotab[] = {
    CONDDEF("len", 0, cond_p_len, 1, 2, 0),
    CONDDEF("ex", CONDF_INFIX, cond_i_ex, 0, 0, 0),
  };

Again a macro is used, with the following arguments:

  - the name of the condition code without the leading hyphen
    (i.e. the example makes the condition codes `-len' and `-ex'
    usable in `[[...]]' constructs)
  - an optional flag which for now can only be CONDF_INFIX; if this is 
    given, an infix operator is created (i.e. the above makes
    `[[ -len str ]]' and `[[ s1 -ex s2 ]]' available)
  - the C-function implementing the conditional
  - for non-infix condition codes the next two arguments give the
    minimum and maximum number of string the conditional can handle
    (i.e. `-len' can get one or two strings); as with builtins giving
    -1 as the maximum number means that the conditional accepts any
    number of strings
  - finally as the last argument an integer that is passed to the
    handler function that can be used to distinguish different
    condition codes if the same C-function implements more than one of 
    them

The definition for the function looks like:

  /**/
  static int
  cond_p_len(char **a, int id)
  {
    ...
  }

The first argument is an array containing the strings (NULL-terminated
like the array of arguments for builtins), the second argument is the
integer value stored in the table (the last argument to `CONDDEF(...)').
The value returned by the function should be non-zero if the condition 
is true and zero otherwise.

Note that no preprocessing is done on the strings. This means that
no substitutions are performed on them and that they will be
tokenized. There are three helper functions available:

  - char *cond_str(args, num, raw)
    The first argument is the array of strings the handler function
    got as an argument and the second one is an index into this array.
    The return value is the num'th string from the array with
    substitutions performed. If the last argument is zero, the string
    will also be untokenized.
  - long cond_val(args, num)
    The arguments are the same as for cond_str(). The return value is
    the result of the mathematical evaluation of the num'th string
    form the array.
  - int cond_match(args, num, str)
    Again, the first two arguments are the same as for the other
    functions. The third argument is any string. The result of the
    function is non-zero if the num'th string from the array taken 
    as a glob pattern matches the given string.

Parameters
----------

For defining parameters, a module can call `createparam()' directly or 
use a table to describe them, e.g.:

  static struct paramdef patab[] = {
    PARAMDEF("foo", PM_INTEGER, NULL, get_foo, set_foo, unset_foo),
    INTPARAMDEF("exint", &intparam),
    STRPARAMDEF("exstr", &strparam),
    ARRPARAMDEF("exarr", &arrparam),
  };

There are four macros used:

  - PARAMDEF() gets as arguments:
    - the name of the parameter
    - the parameter flags to set for it (from the PM_* flags defined
      in zsh.h)
    - optionally a pointer to a variable holding the value of the
      parameter
    - three functions that will be used to get the value of the
      parameter, store a value in the parameter, and unset the
      parameter
  - the other macros provide simple ways to define the most common
    types of parameters; they get the name of the parameter and a
    pointer to a variable holding the value as arguments; they are
    used to define integer-, scalar-, and array-parameters, so the
    variables whose addresses are given should be of type `long',
    `char *', and `char **', respectively

For a description of how to write functions for getting or setting the 
value of parameters, or how to write a function to unset a parameter,
see the description of the following functions in the `params.c' file:

  - `intvargetfn()' and `intvarsetfn()' for integer parameters
  - `strvargetfn()' and `strvarsetfn()' for scalar parameters
  - `arrvargetfn()' and `arrvarsetfn()' for array parameters
  - `stdunsetfn()' for unsetting parameters

Note that if one defines parameters using the last two macros (for
scalars and arrays), the variable holding the value should be
initialized to either `NULL' or to a piece of memory created with
`zalloc()'. But this memory should *not* be freed in the
finish-function of the module because that will be taken care of by
the `deleteparamdefs()' function described below.

It is also possible to declare special parameters using
the macro SPECIALPMDEF().  More care is required in this case.
See, for example, many of the definitions in Src/Modules/parameter.c.

Math functions
--------------

Modules can also define math functions. Again, they are described
using a table:

  static struct mathfunc mftab[] = {
    NUMMATHFUNC("sum", math_sum, 1, -1, 0),
    STRMATHFUNC("length", math_length, 0),
  };

The `NUMMATHFUNC()' macro defines a math function that gets an array
of mnumbers (the zsh type for representing values in arithmetic
expressions) taken from the string in parentheses at the function
call. Its arguments are the name of the function, the C-function
implementing it, the minimum and maximum number of arguments (as
usual, the later may be `-1' to specify that the function accepts any
number of arguments), and finally an integer that is given unchanged
to the C-function (to be able to implement multiple math functions in
one C-function).

The `STRMATHFUNC()' macro defines a math function that gets the string 
in parentheses at the call as one string argument (without the
parentheses). The arguments are the name of the function, the
C-function, and an integer used like the last argument of
`NUMMATHFUNC()'.

The C-functions implementing the math functions look like this:

  /**/
  static mnumber
  math_sum(char *name, int argc, mnumber *argv, int id)
  {
    ...
  }

  /**/
  static mnumber
  math_length(char *name, char *arg, int id)
  {
    ...
  }

Functions defined with `NUMMATHFUNC' get the name of the function, the 
number of numeric arguments, an array with these arguments, and the
last argument from the macro-call. Functions defined with
`STRMATHFUNC' get the name of the function, the string between the
parentheses at the call, and the last argument from the macro-call.

Both types of functions return an mnumber which is a discriminated
union looking like:

  typedef struct {
    union {
      zlong l;
      double d;
    } u;
    int type;
  } mnumber;

The `type' field should be set to `MN_INTEGER' or `MN_FLOAT' and
depending on its value either `u.l' or `u.d' contains the value.

Widgets
-------

As of this writing, widgets are not managed by the features mechanism.
Modules can add builtin widgets by calling `addzlefunction' as defined
in Src/Zle/zle_thingy.c.  Typically this is called from the `boot_'
routine.  Any widgets so added should be removed by `deletezlefunction'
called from the `cleanup_' routine.

Keymaps
-------
Keymaps are created with `newkeymap' and exposed for use with bindkey
by `linkkeymap', both defined in Src/Zle/zle_keymap.c.  Typically the
same name is used both to create and link the keymap.  As with widgets,
there is currently no features mechanism for keymaps, and they should
be initialized in the `boot_' function.  In `cleanup_', first remove
linkage with `unlinkkeymap' and then discard with `deletehashtable'.

Hooks
-----

Modules can also define function hooks. Other modules can then add
functions to these hooks to make the first module call these functions
instead of the default.  These are not handled by the features
mechanism as they are not directly visible to the user.

Again, an array is used to define hooks:

  static struct hookdef foohooks[] = {
    HOOKDEF("foo", foofunc, 0),
  };

The first argument of the macro is the name of the hook. This name
is used whenever the hook is used. The second argument is the default
function for the hook or NULL if no default function exists. The
last argument is used to define flags for the hook. Currently only one
such flag is defined: `HOOKF_ALL'. If this flag is given and more than
one function was added to the hook, all functions will be called
(including the default function). Otherwise only the last function
added will be called.

The functions that can be used as default functions or that can be
added to a hook have to be defined like:

  /**/
  static int
  foofunc(Hookdef h, void *data)
  {
    ...
  }

The first argument is a pointer to the struct defining the hook. The
second argument is an arbitrary pointer that is given to the function
used to invoke hooks (see below).

The functions to register and de-register hooks look like those for
the other things that can be defined by modules:

  /**/
  int
  boot_(Module m)
  {
    int ret;

    ret = addhookdefs(m->nam, foohooks, sizeof(foohooks)/sizeof(*foohooks))
    ...
  }
  ...
  /**/
  int
  cleanup_(Module m)
  {
    deletehookdefs(m->nam, foohooks, sizeof(foohooks)/sizeof(*foohooks));
    ...
  }

Modules that define hooks can invoke the function(s) registered for
them by calling the function `runhook(name, data)'. The first argument 
is the name of the hook and the second one is the pointer given to the 
hook functions as their second argument. Hooks that have the `HOOKF_ALL' 
flag call all function defined for them until one returns non-zero.
The return value of `runhook()' is the return value of the last hook
function called or zero if none was called.

To add a function to a hook, the function `addhookfunc(name, func)' is 
called with the name of the hook and a hook function as arguments.
Deleting them is done by calling `deletehookfunc(name, func)' with the 
same arguments as for the corresponding call to `addhookfunc()'.

Alternative forms of the last three function are provided for hooks
that are changed or called very often. These functions,
`runhookdef(def, data)', `addhookdeffunc(def, func)', and
`deletehookdeffunc(def, func)' get a pointer to the `hookdef'
structure defining the hook instead of the name and otherwise behave
like their counterparts.

The following hooks are defined by the standard set of modules and may be
referenced by other modules.  Each has a corresponding macro name that
points into the definition structure, to avoid repeating the hook names
as strings.

   zsh/main
     after_trap           AFTERTRAPHOOK
     before_trap          BEFORETRAPHOOK
     exit                 EXITHOOK

   zsh/complete
     compctl_make       *  COMPCTLMAKEHOOK
     compctl_cleanup    *  COMPCTLCLEANUPHOOK
     insert_match          INSERTMATCHHOOK
     comp_list_matches  *  COMPLISTMATCHESHOOK
     menu_start            MENUSTARTHOOK

   zsh/zle
     before_complete    *  BEFORECOMPHOOK
     complete           *  COMPLETEHOOK
     after_complete     *  AFTERCOMPHOOK
     accept_completion  *  ACCEPTCOMPHOOK
     list_matches       *  LISTMATCHESHOOK
     invalidate_list    *  INVALIDATELISTHOOK

Hooks marked with "*" do not use the HOOKF_ALL flag and so are replaced if
another module adds a function to the hook.  Use with caution.

Wrappers
--------

Finally, modules can define wrapper functions.  These functions are
called whenever a shell function is to be executed.  Again, they
are not handled by the features mechanism as they are not visible
to the user.

The definition is simple:

  static struct funcwrap wrapper[] = {
    WRAPDEF(ex_wrapper),
  };

The macro `WRAPDEF(...)' gets the C-function as its only argument.
The `boot_()' function must install wrappers by calling `addwrapper()'
like so:

  /**/
  int
  boot_(Module m)
  {
    int ret;

    ret = addwrapper(m, wrapper);
    ...
  }

The `cleanup_()' function should then remove the wrappers again:

  /**/
  int
  cleanup_(Module m)
  {
    deletewrapper(m, wrapper);
    ...
  }

The wrapper function should be defined like:

  /**/
  static int
  ex_wrapper(Eprog prog, FuncWrap w, char *name)
  {
    ...
    runshfunc(prog, w, name);
    ...
    return 0;
  }

The first two arguments should only be used to pass them to
`runshfunc()' which will execute the shell function. The last argument 
is the name of the function to be executed. The arguments passed to
the function can be accessed via the global variable `pparams' (a
NULL-terminated array of strings).

The return value of the wrapper function should be zero if it calls
`runshfunc()' itself and non-zero otherwise. This can be used for
wrapper functions that only need to run under certain conditions or
that don't need to clean anything up after the shell function has
finished:

  /**/
  static int
  ex_wrapper(Eprog prog, FuncWrap w, char *name)
  {
    if (wrapper_need_to_run) {
      ...
      runshfunc(prog, w, name);
      ...
      return 0;
    }
    return 1;
  }

Inside these wrapper functions the global variable `sfcontext' will be 
set to a clue indicating the circumstances under which the shell
function was called. It can have any of the following values:

  - SFC_DIRECT:   the function was invoked directly by the user
  - SFC_SIGNAL:   the function was invoked as a signal handler
  - SFC_HOOK:     the function was automatically invoked as one of the
                  special functions known by the shell (like `chpwd')
  - SFC_WIDGET:   the function was called from the zsh line editor as a
                  user-defined widget
  - SFC_COMPLETE: the function was called from the completion code
                  (e.g. with `compctl -K func')

If a module invokes a shell function (e.g. as a hook function), the
value of this variable should only be changed temporarily and restored
to its previous value after the shell function has finished.

There is a problem when the user tries to unload a module that has
defined wrappers from a shell function. In this case the module can't
be unloaded immediately since the wrapper function is still on the
call stack. The zsh code delays unloading modules until all wrappers
from them have finished. To hide this from the user, the module's
cleanup function is run immediately so that all builtins, condition
codes, and wrapper function defined by the module are
de-registered. But if there is some module-global state that has to be 
finalized (e.g. some memory that has to be freed) and that is used by
the wrapper functions finalizing this data in the cleanup function
won't work.

This is why there are two functions each for the initialization and
finalization of modules. The `boot'- and `cleanup'-functions are run
whenever the user calls `zmodload' or `zmodload -u' and should only
register or de-register the module's interface that is visible to the
user. Anything else should be done in the `setup'- and
`finish'-functions. Otherwise modules that other modules depend upon
may destroy their state too early and wrapper functions in the latter
modules may stop working since the state they use is already destroyed.

Documentation
-------------

* Edit only the .yo files.  All other formats (man pages, TeXinfo, HTML,
  etc.) are automatically generated from the yodl source.

* Always use the correct markup.  em() is used for emphasis, and bf()
  for citations.  tt() marks text that is literal input to or output
  from the shell.  var() marks metasyntactic variables.

* In addition to appropriate markup, always use quotes (`') where
  appropriate.  Specifically, use quotes to mark text that is not a part
  of the actual text of the documentation (i.e., that it is being quoted).
  In principle, all combinations of quotes and markup are possible,
  because the purposes of the two devices are completely orthogonal.
  For example,

      Type `tt(xyzzy)' to let zsh know you have played tt(advent).
      Saying `plugh' aloud doesn't have much effect, however.

  In this case, "zsh" is normal text (a name), "advent" is a command name
  occurring in the main text, "plugh" is a normal word that is being quoted
  (it's the user that says `plugh', not the documentation), and "xyzzy"
  is some text to be typed literally that is being quoted.

* For multiple-line pieces of text that should not be filled, there are
  various models.
  - If the text is pure example, i.e. with no metasyntactic variables etc.,
    it should be included within `example(...)'.  The text will be
    indented, will not be filled and will be put into a fixed width font.
  - If the text includes mixed fonts, it should be included within
    `indent(...)'.  The text is now filled unless `nofill(...)' is also
    used, and explicit font-changing commands are required inside.
  - If the text appears inside some other format, such as for example the
    `item()' list structure, then the instruction `nofill(...)', which
    simply turns off filling should be used; as with `indent(...)',
    explicit font changing commands are required.  This can be used
    without `indent()' when no indentation is required, e.g. if the
    accumulated indentation would otherwise be too long.
  All the above should appear on their own, separated by newlines from the
  surrounding text.  No extra newlines after the opening or before the
  closing parenthesis are required.

A syntax highlighting file for Vim is included, just source tt(Doc/Zsh/.vimrc)
before editing one of the Doc/Zsh/*.yo files.

Module names
------------

Modules have hierarchical names.  Name segments are separated by `/', and
each segment consists of alphanumerics plus `_'.  Relative names are never
used; the naming hierarchy is strictly for organisational convenience.

Top-level name segments should be organisational identifiers, assigned
by the Zsh Development Group and recorded here:

top-level identifier  organisation
--------------------  ------------
x_*                   reserved for private experimental use
zsh                   The Zsh Development Group (contact: <coordinator@zsh.org>)

Below the top level, naming authority is delegated.


Distribution of files
---------------------

zsh is distributed in two parts: a "src" distribution containing all
the source files (roughly, but not exactly, corresponding to the git
tree), and a "doc" distribution containing some pre-built files from
the documentation directory.  All the files in the "doc" distribution
may be generated from files in the "src" distribution with appropriate
freely available tools.

To indicate which files should be distributed, each directory in the git
tree includes a file .distfiles that sets any number of a set of Bourne
shell (scalar) parameters.  The value of the parameter is expanded as a
set of standard command line arguments.  Apart from DISTFILES_NOT, which
must be an explicit list of files separated by whitespace, basic
globbing is allowed in the values.

Because of the way DISTFILES_SRC is constructed it is only possible
to make a release from a git checkout.

The following parameters are currently used:

- DISTFILES_SRC is a list of files from the directory for the "src"
  distribution.  However, if the file .distfiles is present in
  a directory, all files known to git will be added to DISTFILES_SRC
  except for files listed explicitly in DISTFILES_NOT.

- DISTFILES_DOC is a list of files from the directory for the "doc"
  distribution.

- DISTFILES_NOT is a list of files that will not be included in a
  distribution even though they are present in the git tree.
debug log:

solving cbada7de9 ...
found cbada7de9 in https://git.vuxu.org/mirror/zsh/

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).