Next: , Previous: , Up: Methods   [Index]


Templates

Templates

Templates are simplified methods that are defined as macros and written in C. They provide a method-compatible wrapper to C functions.

Template methods can appear in place of C functions in complex expressions, and they must be used if a C function writes to its arguments (e.g., like scanf(3) or sscanf(3)). For example, if we have a template defined for the function myPrintMsg, then Ctalk subsitutes the method expression wherever myPrintMsg appears in an expression like this one.


  if ((myInt = myPrintMsg (someMsg)) != 0) {
     ... do something...
  }

After compilation, the expression looks like this.


  if ((myInt = CFunction cMyPrintMsg (someMsg)) != 0) {
     ...

You can also use myPrintMsg on the left-hand side of an assignment, like this.


  myInt = myPrintMsg (someMsg);

  -or-

  self = myPrintMsg (someMsg);

Additionally, you can use templates on their own, by prefacing the method’s name (the template function’s alias) with its class object.


  CFuntion myPrintMsg (someMsg);

As the last example implies, templates are class methods in the pseudo-class CFunction. Ctalk loads and caches templates where necessary when compiling the input file, so you won’t see any methods of the CFunction class unless the program calls for one or more of them.

If the template wraps a C function of the same name, then, of course, you can also use the C function on its own. However, templates don’t necessarily need to correspond to a C function; they can provide any set of C expressions with a method compatible interface.

Ctalk defines a number of built-in templates for the standard C library. You can determine if Ctalk substitutes a template for a C function by giving the --printtemplates option to ctalk when it compiles a source file. This displays the templates that the compiler loads and caches (but doesn’t necessarily send to the output).

You can define templates for application-specific C functions and routines also. Ctalk retrieves and caches them similarly to its built-in templates, but they are cataloged and stored separately in each user’s ~/.ctalk/templates directory.

As mentioned above, templates don’t need to wrap a function of the same name as the template. That is, myPrintMsg, above, does not have to be an actual function (although you need to prototype it that way). Templates for C library functions always correspond to an actual library function. Program specific templates can serve as a wrapper for any function or set of routines.

When compiling templates, the Ctalk compiler checks the user template registry first. If a user defines a template with the same name as one of Ctalk’s C library templates, then the compiler uses the user’s template instead of Ctalk’s built-in template. That means you can define a template that replaces a C library template.

When creating a template for a function, you need to follow these steps.

Writing Templates

Templates are basically multiple line macros that provide a method selector and method body in a #define preprocessor statement. When Ctalk finds a function name that has a template defined for it, it subsitutes the template name for the function name in the expression, adds the template’s body to the output, and adds the template to the CFunction classes’ initialization.

Templates can accept arguments similarly to methods, and, like methods, they return a C OBJECT *, or NULL.

Here is the template for the myPrintMsg() C function. The template provides a wrapper for the printf(3) function, and, like printf(3), returns an integer value (as an Integer object). The template contains a few features that are part of the template protocol.


#define myPrintMsg \n\
cMyPrintMsg (char *text) {\n\
  char buf[255]; \n\
  int result; \n\
  OBJECT *objresult; \n\
  if (__ctalkIsObject(ARG(0))) {\n\
    result = printf ("myPrintMsg: %s\n", \n\
                      __ctalkToCCharPtr(ARG(0), 1)); \n\
    __ctalkDecimalIntegerToASCII (result, buf); \n\
    return __ctalkCreateObjectInit ("result", "Integer", \n\
                                    "Magnitude", LOCAL_VAR, buf); \n\
  } else { \n\
    __ctalkDecimalIntegerToASCII (-1, buf); \n\
    objresult =  __ctalkCreateObjectInit ("result", "Integer", \n\
                                    "Magnitude", LOCAL_VAR, buf); \n\
    __ctalkRegisterUserObject (objresult); \n\
    return objresult; \n\
  }\n\
}

Cataloging Templates

When looking up templates, Ctalk looks in the template registry file, which is normally ~/.ctalk/templates/fnnames for the name given in the input. If the function is aliased to another name by a macro substitution, fnnames contains the name of the alias also.

For example, on some systems, the function getc(3) is a macro that expands to ‘_IO_getc’. The fnnames file would then contain ‘_IO_getc’ as the templated function’s name.

When the compiler finds the function’s name or alias in fnnames, it looks in the directory for the template file, which is named for the first letter of the function’s name. That is, when looking for myPrintMsg's template, Ctalk looks for a file named ~/.ctalk/templates/m.

The C library templates that come with Ctalk use the same scheme, except that the template files are stored in a subdirectory of the class library called libc. The registry is part or the run-time library, so C library templates do not need a separate registry file.

The manual page, fnnames(5ctalk) contains more information about the fnnames file. The templates(5ctalk) manual page describes the format of individual templates.


Next: , Previous: , Up: Methods   [Index]