xref: /illumos-gate/usr/src/contrib/ast/src/cmd/ksh93/TYPES (revision b30d1939)
1*b30d1939SAndy Fiddaman
2*b30d1939SAndy FiddamanThe ability for users to define types has been added to ksh93t.
3*b30d1939SAndy FiddamanHere is a quick summary of how types are defined and used in ksh93t.
4*b30d1939SAndy FiddamanThis is still a work in progress so some changes and additions
5*b30d1939SAndy Fiddamanare likely.
6*b30d1939SAndy Fiddaman
7*b30d1939SAndy FiddamanA type can be defined either by a shared library or by using the new
8*b30d1939SAndy Fiddamantypeset -T option to the shell.  The method for defining types via
9*b30d1939SAndy Fiddamana shared library is not described here.  However, the source file
10*b30d1939SAndy Fiddamanbltins/enum.c is an example of a builtin that creates enumeration types.
11*b30d1939SAndy Fiddaman
12*b30d1939SAndy FiddamanBy convention, typenames begin with a capitol letter and end in _t.
13*b30d1939SAndy FiddamanTo define a type, use
14*b30d1939SAndy Fiddaman	typeset -T Type_t=(
15*b30d1939SAndy Fiddaman		definition
16*b30d1939SAndy Fiddaman	)
17*b30d1939SAndy Fiddamanwhere definition contains assignment commands, declaration commands,
18*b30d1939SAndy Fiddamanand function definitions.  A declaration command (for example typeset,
19*b30d1939SAndy Fiddamanreadonly, and export), is a built-in that differs from other builtins in
20*b30d1939SAndy Fiddamanthat tilde substitution is performed on arguments after an =, assignments
21*b30d1939SAndy Fiddamando not have to precede the command name, and field splitting and pathname
22*b30d1939SAndy Fiddamanexpansion is not performed on the arguments.
23*b30d1939SAndy FiddamanFor example,
24*b30d1939SAndy Fiddaman	typeset -T Pt_t=(
25*b30d1939SAndy Fiddaman		float -h 'length in inches' x=1
26*b30d1939SAndy Fiddaman		float -h 'width in inches' y=0
27*b30d1939SAndy Fiddaman		integer -S count=0
28*b30d1939SAndy Fiddaman		len()
29*b30d1939SAndy Fiddaman		{
30*b30d1939SAndy Fiddaman			print -r $((sqrt(_.x*_.x + _.y*_.y)))
31*b30d1939SAndy Fiddaman		}
32*b30d1939SAndy Fiddaman		set()
33*b30d1939SAndy Fiddaman		{
34*b30d1939SAndy Fiddaman			(( _.count++))
35*b30d1939SAndy Fiddaman		}
36*b30d1939SAndy Fiddaman	)
37*b30d1939SAndy Fiddaman
38*b30d1939SAndy Fiddamandefines a type Pt_t that has three variables x, y, and count defined as well
39*b30d1939SAndy Fiddamanas the discipline functions len and set.  The variable x has an initial value
40*b30d1939SAndy Fiddamanof 1 and the variable y has an initial value of 0.  The new -h option argument,
41*b30d1939SAndy Fiddamanis used for documentations purposes as described later and is ignored outside
42*b30d1939SAndy Fiddamanof a type definition.
43*b30d1939SAndy Fiddaman
44*b30d1939SAndy Fiddaman
45*b30d1939SAndy FiddamanThe variable count has the new -S attribute which means that it is shared
46*b30d1939SAndy Fiddamanbetween all instances of the type.  The -S option to typeset is ignored
47*b30d1939SAndy Fiddamanoutside of a type definition.  Note the variable named _ that is used inside
48*b30d1939SAndy Fiddamanthe function definition for len and set.  It will be a reference to the
49*b30d1939SAndy Fiddamaninstance of Pt_t that invoked the function.  The functions len and set
50*b30d1939SAndy Fiddamancould also have been defined with function len and function set, but
51*b30d1939SAndy Fiddamansince there are no local variables, the len() and set() form are more
52*b30d1939SAndy Fiddamanefficient since they don't need to set up a context for local variables
53*b30d1939SAndy Fiddamanand for saving and restoring traps.
54*b30d1939SAndy Fiddaman
55*b30d1939SAndy FiddamanIf the discipline function named create is defined it will be
56*b30d1939SAndy Fiddamaninvoked when creating each instance for that type. A function named
57*b30d1939SAndy Fiddamancreate cannot be defined by any instance.
58*b30d1939SAndy Fiddaman
59*b30d1939SAndy FiddamanWhen a type is defined, a declaration built-in command by this name
60*b30d1939SAndy Fiddamanis added to ksh.  As with other shell builtins, you can get the man page
61*b30d1939SAndy Fiddamanfor this newly added command by invoking Pt_t --man.  The information from
62*b30d1939SAndy Fiddamanthe -h options will be embedded in this man page.  Any functions that
63*b30d1939SAndy Fiddamanuse getopts to process arguments will be cross referenced on the generated
64*b30d1939SAndy Fiddamanman page.
65*b30d1939SAndy Fiddaman
66*b30d1939SAndy FiddamanSince Pt_t is now a declaration command it can be used in the definition
67*b30d1939SAndy Fiddamanof other types, for example
68*b30d1939SAndy Fiddaman	typeset -T Rect_t=( Pt_t ur ll)
69*b30d1939SAndy Fiddaman
70*b30d1939SAndy FiddamanBecause a type definition is a command, it can be loaded on first reference
71*b30d1939SAndy Fiddamanby putting the definition into a file that is found on FPATH.
72*b30d1939SAndy FiddamanThus, if this definition is in a file named Pt_t on FPATH, then
73*b30d1939SAndy Fiddamana program can create instances of Pt_t without first including
74*b30d1939SAndy Fiddamanthe definition.
75*b30d1939SAndy Fiddaman
76*b30d1939SAndy FiddamanA type definition is readonly and cannot be unset.  Unsetting non-shared
77*b30d1939SAndy Fiddamanelements of a type restores them to their default value.  Unsetting a
78*b30d1939SAndy Fiddamanshared element has no effect.
79*b30d1939SAndy Fiddaman
80*b30d1939SAndy FiddamanThe Pt_t command is used to create an instance of Pt_t.
81*b30d1939SAndy Fiddaman	Pt_t p1
82*b30d1939SAndy Fiddamancreates an instance named p1 with the initial value for p1.x set to 1
83*b30d1939SAndy Fiddamanand the initial value of p1.y set to 0.
84*b30d1939SAndy Fiddaman	Pt_t p2=(x=3 y=4)
85*b30d1939SAndy Fiddamancreates an instance with the specified initial values.  The len function
86*b30d1939SAndy Fiddamangives the distance of the point to the origin.  Thus, p1.len will output
87*b30d1939SAndy Fiddaman1 and p2.len will output 5.
88*b30d1939SAndy Fiddaman
89*b30d1939SAndy Fiddamanksh93t also introduces a more efficient command substitution mechanism.
90*b30d1939SAndy FiddamanInstead of $(command), the new command substitution ${ command;}
91*b30d1939SAndy Fiddamancan be used.  Unlike (and ) which are always special, the { and } are
92*b30d1939SAndy Fiddamanreserved words and require the space after { and a newline or ; before }.
93*b30d1939SAndy FiddamanUnlike $(), the ${ ;} command substitution executes the command in
94*b30d1939SAndy Fiddamanthe current shell context saving the need to save and restore
95*b30d1939SAndy Fiddamanchanges, therefore also allowing side effects.
96*b30d1939SAndy Fiddaman
97*b30d1939SAndy FiddamanWhen trying to expand an element of a type, if the element does not exist,
98*b30d1939SAndy Fiddamanksh will look for a discipline function with that name and treat this as if
99*b30d1939SAndy Fiddamanit were the ${ ;} command substitution.  Thus, ${p1.len} is equivalent to
100*b30d1939SAndy Fiddaman${ p1.len;} and within an arithmetic expression, p1.len will be expanded
101*b30d1939SAndy Fiddamanvia the new command substitution method.
102*b30d1939SAndy Fiddaman
103*b30d1939SAndy FiddamanThe type of any variable can be obtained from the new prefix
104*b30d1939SAndy Fiddamanoperator @.  Thus, ${@p1} will output Pt_t.
105*b30d1939SAndy Fiddaman
106*b30d1939SAndy FiddamanBy default, each instance inherits all the discipline functions defined
107*b30d1939SAndy Fiddamanby the type definition other than create.  However, each instance can define
108*b30d1939SAndy Fiddamana function by the same name that will override this definition.
109*b30d1939SAndy FiddamanHowever, only discipline functions with the same name as those defined
110*b30d1939SAndy Fiddamanby the type or the standard get, set, append, and unset disciplines
111*b30d1939SAndy Fiddamancan be defined by each instance.
112*b30d1939SAndy Fiddaman
113*b30d1939SAndy FiddamanEach instance of the type Pt_t behaves like a compound variable except
114*b30d1939SAndy Fiddamanthat only the variables defined by the type can be referenced or set.
115*b30d1939SAndy FiddamanThus, p2.x=9 is valid, but p2.z=9 is not.  Unless a set discipline function
116*b30d1939SAndy Fiddamandoes otherwise, the value of $p1 will be expanded to the form of a compound
117*b30d1939SAndy Fiddamanvariable that can be used for reinput into ksh.
118*b30d1939SAndy Fiddaman
119*b30d1939SAndy FiddamanIf the variables var1 and var2 are of the same type, then the assignment
120*b30d1939SAndy Fiddaman	var2=var1
121*b30d1939SAndy Fiddamanwill create a copy of the variable var1 into var2.  This is equivalent to
122*b30d1939SAndy Fiddaman	eval var2="$var1"
123*b30d1939SAndy Fiddamanbut is faster since the variable does not need to get expanded or reparsed.
124*b30d1939SAndy Fiddaman
125*b30d1939SAndy FiddamanThe type Pt_t can be referenced as if it were a variable using the name
126*b30d1939SAndy Fiddaman.sh.type.Pt_t.  To change the default point location for subsequent
127*b30d1939SAndy Fiddamaninstances of Pt_t, you can do
128*b30d1939SAndy Fiddaman	.sh.type.Pt_t=(x=5 y=12)
129*b30d1939SAndy Fiddamanso that
130*b30d1939SAndy Fiddaman	Pt_t p3
131*b30d1939SAndy Fiddaman	p3.len
132*b30d1939SAndy Fiddamanwould be 13.
133*b30d1939SAndy Fiddaman
134*b30d1939SAndy FiddamanTypes can be defined for simple variables as well as for compound
135*b30d1939SAndy Fiddamanobjects such as Pt_t.  In this case, the variable named . inside
136*b30d1939SAndy Fiddamanthe definition refers to the real value for the variable.  For example,
137*b30d1939SAndy Fiddamanthe type definition
138*b30d1939SAndy Fiddaman	typeset -T Time_t=(
139*b30d1939SAndy Fiddaman		integer .=0
140*b30d1939SAndy Fiddaman		_='%H:%M:%S'
141*b30d1939SAndy Fiddaman		get()
142*b30d1939SAndy Fiddaman		{
143*b30d1939SAndy Fiddaman			.sh.value=$(printf "%(${_._})T" "#$((_))" )
144*b30d1939SAndy Fiddaman		}
145*b30d1939SAndy Fiddaman		set()
146*b30d1939SAndy Fiddaman		{
147*b30d1939SAndy Fiddaman			.sh.value=$(printf "%(%#)T" "${.sh.value}")
148*b30d1939SAndy Fiddaman
149*b30d1939SAndy Fiddaman		}
150*b30d1939SAndy Fiddaman	)
151*b30d1939SAndy Fiddaman
152*b30d1939SAndy FiddamanThe sub-variable name _ is reserved for data used by discipline functions
153*b30d1939SAndy Fiddamanand will not be included with data written with the %B option to printf.
154*b30d1939SAndy FiddamanIn this case it is used to specify a date format.
155*b30d1939SAndy Fiddaman
156*b30d1939SAndy FiddamanIn this case
157*b30d1939SAndy Fiddaman	Time_t t1 t2=now
158*b30d1939SAndy Fiddamanwill define t1 as the time at the beginning of the epoch and t2
159*b30d1939SAndy Fiddamanas the current time.  Unlike the previous case, $t2 will output
160*b30d1939SAndy Fiddamanthe current time in the date format specified by the value t2._.
161*b30d1939SAndy FiddamanHowever, the value of ${t2.} will expand the instance to a form
162*b30d1939SAndy Fiddamanthat can be used as input to the shell.
163*b30d1939SAndy Fiddaman
164*b30d1939SAndy FiddamanFinally, types can be derived from an existing type.  If the first
165*b30d1939SAndy Fiddamanelement in a type definition is named _, then the new type
166*b30d1939SAndy Fiddamanconsists of all the elements and discipline functions from the
167*b30d1939SAndy Fiddamantype of _ extended by elements and discipline functions defined
168*b30d1939SAndy Fiddamanby new type definition.  For example,
169*b30d1939SAndy Fiddaman
170*b30d1939SAndy Fiddaman	typeset -T Pq_t=(
171*b30d1939SAndy Fiddaman		Pt_t _
172*b30d1939SAndy Fiddaman		float z=0.
173*b30d1939SAndy Fiddaman		len()
174*b30d1939SAndy Fiddaman		{
175*b30d1939SAndy Fiddaman			print -r $((sqrt(_.x*_.x + _.y*_.y + _.z*_.z)))
176*b30d1939SAndy Fiddaman		}
177*b30d1939SAndy Fiddaman	)
178*b30d1939SAndy Fiddaman
179*b30d1939SAndy Fiddamandefines a new type Pq_t which is based on Pq_t and contains an additional
180*b30d1939SAndy Fiddamanfield z and a different len discipline function.  It is also possible
181*b30d1939SAndy Fiddamanto create a new type Pt_t based on the original Pt_t.  In this case
182*b30d1939SAndy Fiddamanthe original Pt_t is no longer accessible.
183