Files
linguist/samples/Pan/types.pan
James Adams 8d178bfaed Improve Pan language support (#3691)
* Add a larger set of sample files for Pan

This is a fairly good cross section of Pan based on code from:
* https://github.com/quattor/template-library-examples
* https://github.com/quattor/template-library-core

* Add Pan language grammar
2017-07-03 18:49:15 +02:00

152 lines
4.2 KiB
Plaintext

@contributor{
name = First Contributor
email = first@example.org
}
@contributor{
name = Second Contributor
email = second@example.org
}
@documentation{
Data type and function definitions for basic types
}
declaration template pan/types;
include 'pan/legacy';
@documentation{
This type implements a date/time format consistent with
ASN.1 typically used by LDAP. The actual specification is the
"GeneralizedTime" format as specified on page 38 of the X.208
ITU-T recommendation and references within.
Ex: 20040825120123Z
20040825120123+0100
20040825120123,5
20040825120123.5
20040825120123.5-0123
}
function is_asndate = {
# Check cardinality and type of argument.
if (ARGC != 1 || !is_string(ARGV[0]))
error("usage: is_asndate(string)");
# Match the datetime pattern, extracting interesting fields.
result = matches(ARGV[0],
'^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(?:[,\.](\d+))?([Zz]|(?:[-+]\d{2}\d{2}))?$');
if (length(result) >= 7) {
# Do further tests on various components of the date.
# NOTE: the to_long(to_double(x)) construct below is to avoid having
# the to_long function treat strings with leading zeros as octal
# numbers. E.g. to_long("09") will throw an exception because '9' is
# not a valid octal digit.
year = to_long(result[1]);
month = to_long(to_double(result[2]));
day = to_long(to_double(result[3]));
hour = to_long(to_double(result[4]));
minute = to_long(to_double(result[5]));
second = to_long(to_double(result[6]));
frac = 0;
if (length(result) > 7) {
frac = to_long(to_double(result[7]));
};
zone = '+0000';
if (length(result) > 8) {
zone = result[8];
};
# Check the range of months.
if (month < 1 || month > 12) {
error("is_asndate: invalid month");
return(false);
};
# Check the range of days.
if (day < 1 || day > 31) {
error("is_asndate: invalid day");
return(false);
};
# Be more specific on the days in each month.
if (month == 4 || month == 6 || month == 9 || month == 11) {
if (day > 30) {
error("is_asndate: invalid day");
};
};
# February is always a bother. Too lazy to check that the leap
# years have been specified correctly.
if (month == 2 && day > 29) {
error("is_asndate: invalid day");
};
# Check the time.
if (hour > 23) {
error("is_asndate: invalid hour");
return(false);
};
if (minute > 59) {
error("is_asndate: invalid minute");
return(false);
};
# Allow for leap seconds here (since it is easy).
if (second > 60) {
error("is_asndate: invalid minute");
return(false);
};
# Check the time zone format.
if (zone != "Z" && zone != "z") {
tz = matches(zone, '^[-+](\d{2})(\d{2})$');
hoffset = to_long(to_double(tz[1]));
moffset = to_long(to_double(tz[2]));
if (hoffset >= 12) {
error("is_asndate: invalid hour offset in time zone");
return(false);
};
if (moffset > 59) {
error("is_asndate: invalid minute offset in time zone");
return(false);
};
};
} else {
error("is_asndate: invalid format for time");
return(false);
};
# If it gets to this point, then the date must be OK.
true;
};
type type_asndate = string with {
is_asndate(SELF);
};
@documentation{
desc = Type that enforces the existence of a named interface.
}
type valid_interface = string with {
if (exists(format('/system/network/interfaces/%s', SELF))) {
return(true);
};
foreach(ifc; attr; value('/system/network/interfaces')) {
if (attr['device'] == SELF){
return(true);
};
};
false;
};
@documentation{
desc = CPU architectures understood by Quattor
}
type cpu_architecture = string with match (SELF, '^(i386|ia64|x86_64|sparc|aarch64|ppc64(le)?)$');