next up previous contents
Next: Programming with the xtract Up: The xtract macro language Previous: Output filters   Contents

Subsections


Internal design

The xtract macros are first interpreted and then compiled in the memory. This complied code is then executed for every input data record. The details about the compilation and execution of the format string are given below.

Macro compilation

The process of compilation of the format string involves two steps.

First, all the loops represented by the operators in the macro are exploded into a linked list (also called the symbol table), with each node of the list corresponding to a valid element of the language. Each element is represented in the memory by a structure of the following type:


                 typedef struct StructSymbType {
                   char Name[NAMELEN];
                   char Fmt[FMTLEN];
                   int abc[3];
                   unsigned int Type;
                   float (*func)(char *,float **,int);
                   float *fargv[NARGV];
                   int fargc;
                   float *ptr;
                   struct StructSymbType *next;
                 } SymbType;


All recognized elements (symbols) are tabulated in the memory in a temporary table, which is a list of structure of the following type:


                 typedef struct TT {
                   char *Name;
                   unsigned int Class,Type;
                 } TypeTable;


This table is hard-coded in the file table.h and is used only to validate the symbols in the macro. Once validated, the Class and Type information for this table is transfered to the actual symbol table and the temporary table destroyed.

Apart from the name of the element and the C styled format string, the nodes of the symbol table also have information about the mechanism to get the numeric value associated with the element. This information is in the field Type of the structure above. Valid types for the elements are listed in Table B.2.


Table B.2: Table of element types in xtract macro language
Type Meaning
CHARType Represents a character to output
FTYPE Function type: the value will be
  returned by a call to the function func
PTYPE Pointer type: the value will be in the buffer
  at the location pointed to by ptr

The abc field of the element structure shown earlier, holds the values of the three operators (ant,base, and chan) applicable to the element.

Before an element is added to the symbol table, a check is made to ensure that all the required operators (listed in Table B.1) are active. To generate this information about the required operators, elements are further categorized into one of the classes listed in Table B.3.


Table B.3: Table of valid classes of the elements of xtract macro language
Class Operators Required
IV None
AV ant
BV base
CV chan
BCV base,chan
ABCV ant,base,chan

Once the element is validated for the required active operators, a new link is created in the symbol table and filled with the Name, Type and Class of the element. By this time, the loops (represented by the list of values associated with various operators) have already been exploded (i.e., a node created in the symbol table for each value of the operator). Information about the values of the operators is transfered to the symbol table for every value of the active operators and the values of the required operators are put in the abc array (passive operators are assigned a value of $ -1$). By this time, if no error has occurred, it is assured that the syntax was correct and all the elements in the macro were recognized.

Second step in the process of compilation is to fill in the information about the mechanism to get the numeric values of each elements in the list. The Type of the element and, if required, the values in the abc array are used for filling in this information.

For elements of type PTYPE , the ptr field is made to point to the location in the memory where the required value is to be found. This type of element refer to particular values in the buffer in the memory and need the offsets in the buffer which can be computed using the abc array. The buffer in the memory is generally the buffer in which data records from the LTA-file is read. Examples of this kind of elements are $ IST$, real/imaginary values of the visibility, etc.

For elements of type FTYPE, the func field is filled with a pointer to a function which will be called when the value of the element is required. If the computation of the value requires some data, the pointers to this data is put in the field fargv and the total number of such pointer is put in the field fargc. These will be passed as arguments to the function when the value of the element is required. The first argument passed to the function will be the name of the element. Examples of this kind of elements are $ HA$, amplitude/phase of the visibility, etc.

For elements of type CHARType, nothing needs to be done. The name of such elements is the character that is to be copied to the output during execution.

Macro execution

The process of ``execution'' of the compiled list of elements is rather simple. The program steps through the entire list of elements and checks the type of each element on the list. If the type is PTYPE, the value of memory location to which ptr points, is copied to the output stream using the format in the Fmt field of the element. If the type is FTYPE, the function specified by func is called with Name, fargv, and fargc as the arguments. The value returned by this function is then copied to the output stream using the format in the Fmt field of the element. If the type is CHARType, the first character of the Name field is copied to the output stream.

Following is an example of a simple routine used for execution of the compiled macros:

 /* $Id: xtract.tex,v 1.9 2000/02/18 03:58:24 sanjay Exp sanjay $ */
 #include <stdio.h>
 #include <fmt.h>

 int ExecuteDef(FILE *fd,SymbType *P,float *buf,int len)
 {
   SymbType *i;
   int N=0;

   for (i=P;i;i=i->next)
     {
      switch(i->Type)
        {
         case PType:
          {buf[N++]= *i->ptr;break;}
         case FType:
          {buf[N++]=i->func(i->Name,i->fargv,i->fargc);break;}
         case CHARType: return N;
         default:
           fprintf(stderr,"###Error: Unknown type in ExecuteDef\n");
        }
     }
   return N;
 }
If the output in required is the binary format, one can write an equivalent Execute routine, which will ignore the Fmt field and CHARType elements and output the values in the binary format.


next up previous contents
Next: Programming with the xtract Up: The xtract macro language Previous: Output filters   Contents
Sanjay Bhatnagar 2005-07-07