File: using_eproctypes2.inc

package info (click to toggle)
critcl 3.3.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 9,680 kB
  • sloc: ansic: 41,058; tcl: 12,090; sh: 7,230; pascal: 3,456; asm: 3,058; ada: 1,681; cpp: 1,001; cs: 879; makefile: 333; perl: 104; xml: 95; f90: 10
file content (100 lines) | stat: -rw-r--r-- 3,110 bytes parent folder | download | duplicates (3)
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
[subsection {Custom Types, Semi-trivial}]

A more involved custom argument type would be to map from Tcl strings
to some internal representation, like an integer code.

[para] The first example is taken from the [package tclyaml] package,
a binding to the [package libyaml] library. In a few places we have to
map readable names for block styles, scalar styles, etc. to the
internal enumeration.

[example {
    critcl::argtype yaml_sequence_style_t {
        if (!encode_sequence_style (interp, @@, &@A)) return TCL_ERROR;
    }

    ...

    critcl::ccode {
        static const char* ty_block_style_names [] = {
            "any", "block", "flow", NULL
        };

        static int
        encode_sequence_style (Tcl_Interp* interp, Tcl_Obj* style,
                               yaml_sequence_style_t* estyle)
        {
            int value;
            if (Tcl_GetIndexFromObj (interp, style, ty_block_style_names,
                                     "sequence style", 0, &value) != TCL_OK) {
                return 0;
            }
            *estyle = value;
            return 1;
        }
    }

    ...

    method sequence_start proc {
        pstring anchor
        pstring tag
        int implicit
        yaml_sequence_style_t style
    } ok {
        /* Syntax: <instance> seq_start <anchor> <tag> <implicit> <style> */
        ...
    }

    ...
}]

It should be noted that this code precedes the advent of the
supporting generator package [package critcl::emap]. using the
generator the definition of the mapping becomes much simpler:

[example {
    critcl::emap::def yaml_sequence_style_t {
        any   0
        block 1
        flow  2
    }
}]

Note that the generator will not only provide the conversions, but
also define the argument and result types needed for their use by
[cmd critcl::cproc].

Another example of such a semi-trivial argument type can be found in
the [package CRIMP] package, which defines a [type Tcl_ObjType] for
[term image] values. This not only provides a basic argument type for
any image, but also derived types which check that the image has a
specific format. Here we see for the first time non-integer arguments,
and the need to define the C types used for variables holding the C
level value, and the type of function parameters (Due to C promotion
rules we may need different types).

[example {
    critcl::argtype image {
        if (crimp_get_image_from_obj (interp, @@, &@A) != TCL_OK) {
            return TCL_ERROR;
        }
    } crimp_image* crimp_image*

    ...

        set map [list <<type>> $type]
        critcl::argtype image_$type [string map $map {
            if (crimp_get_image_from_obj (interp, @@, &@A) != TCL_OK) {
                return TCL_ERROR;
            }
            if (@A->itype != crimp_imagetype_find ("crimp::image::<<type>>")) {
                Tcl_SetObjResult (interp,
                                  Tcl_NewStringObj ("expected image type <<type>>",
                                                    -1));
                return TCL_ERROR;
            }
        }] crimp_image* crimp_image*

    ...
}]