next up previous top
Up: Property
Previous: Variant

User Defined Properties

Description

User-defined properties are hooks in the UniCon language for allowing users to specify additional information about a UniCon construct that is not further interpreted in the language or by the UniCon compiler. The name part of a user-defined property can be any <identifier> that is not already the name part of a pre-defined UniCon property. The value part of a property must be a <string>. This string is not parsed, nor further interpreted, by the UniCon compiler.

The information specified in a user-defined property is stored in the parse tree that the
UniCon compiler creates while processing UniCon definitions. At an appropriate step in the compilation or build process, the compiler can collect the information associated with a user-defined property and ship it off to an external tool that might need the information.

NOTE: For now, the means for communicating with external tools is builtin to the compiler. Therefore, adding a new tool to the suite of external tools that are known to UniCon requires modification of the UniCon compiler source code. Since this is not a trivial task, this may require help from the UniCon compiler developers.

As mentioned above, the UniCon compiler does not parse or further interpret the value part of a user-defined property. There are hooks in the source code of the compiler, however, for the user to supply C source code fragments to parse and check the semantics of the value part. The UniCon compiler will execute these code fragments at the appropriate times during the compilation and build process.

The UniCon compiler calls two functions when it encounters a user-defined property. The first is a function that executes user-supplied C source code fragments to parse the value part of user-defined properties. The second is a function that executes user-supplied C source code fragments to check the semantics of the value part of user-defined properties.

The first function, uni_user_parse, is the hook in the UniCon compiler for users to add C source code that parses the value of a user-defined property. If the user wishes to have the UniCon compiler parse the value of a user-defined property, (s)he must supply a parsing function with the source code of the UniCon compiler that can be compiled and linked with the other UniCon source when building it. The user adds a C source code fragment directly to the first function, uni_user_parse, in the UniCon source file uni_user_defined.c to parse the value of a user-defined property. The following is an example of such a fragment:

   if (uni_strcmp_l (av_pair->attribute_str->string,
     "some_user_defined_property") == 0)
     return my_user_defined_property_parser ( 
      av_pair->value.user);
In the above example, the function uni_strcmp_l is a utility function provided by the UniCon compiler. The letter "l" in the name refers to the leftmost argument in the argument list. This function performs a string comparison using the C standard library routine strcmp, but first it converts the value of the leftmost argument to lower case letters. The UniCon compiler also provides the two functions uni_strcmp_r and uni_strcmp_b which convert the value of the rightmost argument, and the values of both arguments, to lower case letters, respectively. The return values of these three functions have the same semantics as the return value of the strcmp function.

Also, notice that my_user_defined_property_parser is a user-supplied function that parses the value of the property. All of the information about a particular property is contained in the argument named av_pair, supplied as input to the uni_user_parse routine. av_pair->attribute_str->string points to the string value that is the name part of the property, and av_pair->value.user points to the string value that is the value part of the property. The return value of the user-supplied property parser must be a pointer value. It can be a pointer to an object of any type, since UniCon does not further interpret this value.

The second function, uni_user_semantics, is the hook in the UniCon compiler for users to add C source code that checks the semantics of the value of a user-defined property. If the user wishes to have the UniCon compiler check the semantics of the value of a user-defined property, (s)he must supply a semantics checking function with the source code of the UniCon compiler that can be compiled and linked with the other UniCon source when building it. The user adds a C source code fragment directly to the second function, uni_user_semantics, in the UniCon source file uni_user_defined.c to check the semantics of the value of a user-defined property. The following is an example of such a fragment:

   if (uni_strcmp_l (av_pair->attribute_str->string,
     "some_user_defined_property") == 0)
     return check_my_user_defined_property_semantics ( 
      av_pair->value.user_temp);
Notice that check_my_user_defined_property_semantics is a user-supplied function that checks the semantics of the value part of the property. Also, notice that the argument supplied to this function is av_pair->value.user_temp, rather than av_pair->value.user. This is because the function uni_user_parse places the pointer to the parsed value part of a user-defined property there. The return value of the user-supplied property semantic checker must be a pointer value. It can be a pointer to an object of any type, since UniCon does not further interpret this value.

To include the source files containing the user-supplied parsing and semantic checking functions in the build process, modify the Odinfile in the following UniCon installation directory: ...UniCon/uparse/src. Add a separate line for each file to the uparse system model in the following way. Assume you wish to add the functions in the source files my_parsers.c and my_checkers.c to the UniCon compiler. The system model used to build the original compiler looks as follows:

  %uparse.c.sm == <<
    uni_error.c +define=UNI_ERROR_ROUTINE
    uni_lexer.l
    uni_main.c
    uni_parser.y
    uni_tree_builder.c
    uni_semantic.c
    uni_list.c
    uni_user_defined.c
    uni_builder.c
    uni_datause.c
    uni_fileio.c
    uni_proccall.c
    uni_rproccall.c
    uni_pipe.c
    uni_rts.c
    uni_unparse.c
    uni_utility.c +define=UNI_PROGRESS_ROUTINE
Simply add the names of the files as separate lines to the end of the system model so that it looks as follows. Be sure to include full directory path information for the new files. It is not recommended that you keep the source in the same directory with the other UniCon source. This is because when you delete an old UniCon installation in order to build a new one, you may forget your source files are there and accidentally delete them:

  %uparse.c.sm == <<
    uni_error.c +define=UNI_ERROR_ROUTINE
    uni_lexer.l
    uni_main.c
    uni_parser.y
    uni_tree_builder.c
    uni_semantic.c
    uni_list.c
    uni_user_defined.c
    uni_builder.c
    uni_datause.c
    uni_fileio.c
    uni_proccall.c
    uni_rproccall.c
    uni_pipe.c
    uni_rts.c
    uni_unparse.c
    uni_utility.c +define=UNI_PROGRESS_ROUTINE
    /usr/gz/my_parsers.c
    /usr/gz/my_checkers.c
Then, change directory to the root of the installation directory (i.e., ...UniCon) and invoke odin to build uparse: "odin %install_uparse".

Property Lists

A user-defined property can be specified in any property list in the UniCon language.

Value Syntax

The syntax of the value part of a user-defined property is a <string>, enclosed in parentheses. The <string> is uninterpreted by the UniCon compiler. The syntax of the name part of a user-defined property is an <identifier> that is not the name part of any other UniCon property.

Required Rule

OPTIONAL

User-defined properties, of course, are always optional. If specified, however, there must be a corresponding entry for the propery in a file named "user_defined_properties" in the same directory in the file system from which the UniCon compiler is invoked (i.e., the "local" directory). The entry must be a single line with three fields. The first field is the name of the property, and the other two fields can be anything. All three fields are separated from each other by whitespace. The purpose of the second and third fields has not yet been fixed. These are place holders for future enhancements. The case of the letters for the name in the first field is insignificant.

Merge Rule

REPLACE

Subsequent specifications of a user-defined property in a single property list replace earlier specifications (i.e., the last specification is the one that the UniCon compiler uses). Two user-defined attributes are duplicates if the name part is identical (the case of the letters is insignificant) and the value part is identical (the case of the letters is significant for the value part).

Semantic Checks

The UniCon compiler does not perform syntax and semantic checks on, nor further interprets, the value of a user-defined property. However, there are hooks for the maintainer of the UniCon compiler to add C source code fragments that will parse and perform semantic checks on the value part. Please refer to the Description section above for more information.

Example

The following are examples of specifications of user-defined properties. All three examples below are real. The UniCon graphical editor uses these properties to store graphical positioning and sizing information, as well as UniCon source file location information in
UniCon textual definitions. Two of these user-defined properties are embedded in the property list of the composite implementation of the component definition. The third is embedded in the property list of a component instantiation in the composite implementation. Notice that the value parts are actually Scheme data:

  COMPONENT KWIC
    INTERFACE IS
      TYPE Filter
      PLAYER input IS StreamIn
        SIGNATURE ("line")
        PORTBINDING (stdin)
      END input
      PLAYER output IS StreamOut
        SIGNATURE ("line")
        PORTBINDING (stdout)
      END output
      PLAYER error IS StreamOut
        SIGNATURE ("line")
        PORTBINDING (stderr)
      END error
    END INTERFACE
    IMPLEMENTATION IS
      GUI-SCREEN-SIZE ("(list :real-width 800 :width-unit "" :real-height 350 :height-unit "")")
      DIRECTORY ("(list "/usr/examples/upcase.uni" "/usr/examples/cshift.uni" "/usr/examples/data.uni" "/usr/examples/converge.uni" "/usr/examples/sort.uni" "/usr/examples/unix-pipe.uni" "/usr/examples/reverse-f.uni")")
      USES caps INTERFACE upcase
        GUI-SCREEN-POSITION ("(list :position (@pos 68 123) :player-positions (list (cons "input" (cons `left 0.5)) (cons "error" (cons `right 0.6625)) (cons "output" (cons `right 0.3375))))")
      END caps
      (remaining definition omitted)
    END IMPLEMENTATION
  END KWIC

next up previous top
Up: Property
Previous: Variant

Comments? Mail the current maintainer of this page.

Author: Gregory Zelesnik

Last Modified: May 12, 1996