mirror of
https://github.com/ubf/ubf.git
synced 2026-04-16 17:55:48 +00:00
Align UBF's predefined and builtin types with EEP 8
This commit is contained in:
@@ -32,24 +32,24 @@
|
||||
%%% Macros
|
||||
%%%-------------------------------------------------------------------
|
||||
|
||||
%% @doc ubf string helper
|
||||
-define(S(X),
|
||||
#'#S'{value=X}).
|
||||
|
||||
%% @doc ubf proplist helper
|
||||
-define(P(X),
|
||||
#'#P'{value=X}).
|
||||
|
||||
%% @doc ubf string helper
|
||||
-define(S(X),
|
||||
#'#S'{value=X}).
|
||||
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% Records
|
||||
%%%-------------------------------------------------------------------
|
||||
|
||||
%% @doc ubf string record
|
||||
-record('#S',
|
||||
{value="" :: string()}).
|
||||
|
||||
%% @doc ubf proplist record
|
||||
-record('#P',
|
||||
{value=[] :: [{term(),term()}]}).
|
||||
|
||||
%% @doc ubf string record
|
||||
-record('#S',
|
||||
{value="" :: string()}).
|
||||
|
||||
-endif. % -ifndef(ubf)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
+NAME("irc").
|
||||
|
||||
+VSN("ubf1.0").
|
||||
+VSN("ubf2.0").
|
||||
|
||||
+STATE start
|
||||
logon() => proceed() & active. %% Nick randomly assigned
|
||||
@@ -18,8 +18,8 @@
|
||||
EVENT => changeNameEvent(). %% Nick changes name
|
||||
|
||||
+ANYSTATE
|
||||
info() => string();
|
||||
description() => string();
|
||||
info() => ubfstring();
|
||||
description() => ubfstring();
|
||||
contract() => term().
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
+NAME("irc").
|
||||
|
||||
+VSN("ubf1.0").
|
||||
+VSN("ubf2.0").
|
||||
|
||||
+TYPES
|
||||
info() :: info;
|
||||
@@ -9,10 +9,10 @@ contract() :: contract;
|
||||
|
||||
ok() :: ok;
|
||||
bool() :: true | false;
|
||||
nick() :: string();
|
||||
nick() :: ubfstring();
|
||||
oldnick() :: nick();
|
||||
newnick() :: nick();
|
||||
group() :: string();
|
||||
group() :: ubfstring();
|
||||
groups() :: [group()];
|
||||
|
||||
logon() :: logon;
|
||||
@@ -21,9 +21,9 @@ listGroups() :: groups;
|
||||
joinGroup() :: {join, group()};
|
||||
leaveGroup() :: {leave, group()};
|
||||
changeNick() :: {nick, nick()};
|
||||
msg() :: {msg, group(), string()};
|
||||
msg() :: {msg, group(), ubfstring()};
|
||||
|
||||
msgEvent() :: {msg, nick(), group(), string()};
|
||||
msgEvent() :: {msg, nick(), group(), ubfstring()};
|
||||
joinEvent() :: {joins, nick(), group()};
|
||||
leaveEvent() :: {leaves, nick(), group()};
|
||||
changeNameEvent() :: {changesName, oldnick(), newnick(), group()}.
|
||||
@@ -44,8 +44,8 @@ changeNameEvent() :: {changesName, oldnick(), newnick(), group()}.
|
||||
EVENT => changeNameEvent(). %% Nick changes name
|
||||
|
||||
+ANYSTATE
|
||||
info() => string();
|
||||
description() => string();
|
||||
info() => ubfstring();
|
||||
description() => ubfstring();
|
||||
contract() => term().
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
+NAME("irc_types").
|
||||
|
||||
+VSN("ubf1.0").
|
||||
+VSN("ubf2.0").
|
||||
|
||||
+TYPES
|
||||
info() :: info;
|
||||
@@ -9,10 +9,10 @@ contract() :: contract;
|
||||
|
||||
ok() :: ok;
|
||||
bool() :: true | false;
|
||||
nick() :: string();
|
||||
nick() :: ubfstring();
|
||||
oldnick() :: nick();
|
||||
newnick() :: nick();
|
||||
group() :: string();
|
||||
group() :: ubfstring();
|
||||
groups() :: [group()];
|
||||
|
||||
logon() :: logon;
|
||||
@@ -21,9 +21,9 @@ listGroups() :: groups;
|
||||
joinGroup() :: {join, group()};
|
||||
leaveGroup() :: {leave, group()};
|
||||
changeNick() :: {nick, nick()};
|
||||
msg() :: {msg, group(), string()};
|
||||
msg() :: {msg, group(), ubfstring()};
|
||||
|
||||
msgEvent() :: {msg, nick(), group(), string()};
|
||||
msgEvent() :: {msg, nick(), group(), ubfstring()};
|
||||
joinEvent() :: {joins, nick(), group()};
|
||||
leaveEvent() :: {leaves, nick(), group()};
|
||||
changeNameEvent() :: {changesName, oldnick(), newnick(), group()}.
|
||||
|
||||
@@ -109,23 +109,23 @@ STRING = DQUOTE *(%x20-21 / %x23-7E) DQUOTE
|
||||
|
||||
NONEMTPYSTRING = DQUOTE 1*(%x20-21 / %x23-7E) DQUOTE
|
||||
|
||||
predefinedtype = ('atom' "(" [atomattrs] ")")
|
||||
/ ('boolean' "(" [booleanattrs] ")")
|
||||
predefinedtype = ('any' "(" [anyattrs] ")")
|
||||
/ ('none' "(" [noneattrs] ")")
|
||||
/ ('atom' "(" [atomattrs] ")")
|
||||
/ ('binary' "(" [binaryattrs] ")")
|
||||
/ ('float' "(" [floatattrs] ")")
|
||||
/ ('integer' "(" [integerattrs] ")")
|
||||
/ ('list' "(" [listattrs] ")")
|
||||
/ ('proplist' "(" [proplistattrs] ")")
|
||||
/ ('string' "(" [stringattrs] ")")
|
||||
/ ('term' "(" [termattrs] ")")
|
||||
/ ('tuple' "(" [tupleattrs] ")")
|
||||
/ ('none' "(" [noneattrs] ")")
|
||||
|
||||
anyattrs = anyattr
|
||||
/ (anyattr *WSP "," *WSP anyattrs)
|
||||
|
||||
noneattrs = *WSP
|
||||
|
||||
atomattrs = atomattr
|
||||
/ (atomattr *WSP "," *WSP atomattrs)
|
||||
|
||||
booleanattrs = *WSP
|
||||
|
||||
binaryattrs = binaryattr
|
||||
/ (binaryattr *WSP "," *WSP binaryattrs)
|
||||
|
||||
@@ -136,24 +136,11 @@ integerattrs = *WSP
|
||||
listattrs = listattr
|
||||
/ (listattr *WSP "," *WSP listattrs)
|
||||
|
||||
proplistattrs = proplistattr
|
||||
/ (proplistattr *WSP "," *WSP proplistattrs)
|
||||
|
||||
stringattrs = stringattr
|
||||
/ (stringattr *WSP "," *WSP stringattrs)
|
||||
|
||||
termattrs = termattr
|
||||
/ (termattr *WSP "," *WSP termattrs)
|
||||
|
||||
tupleattrs = tupleattr
|
||||
/ (tupleattr *WSP "," *WSP tupleattrs)
|
||||
|
||||
noneattrs = *WSP
|
||||
|
||||
anyattr = 'nonempty' / 'nonundefined'
|
||||
atomattr = 'ascii' / 'asciiprintable' / 'nonempty' / 'nonundefined'
|
||||
binaryattr = 'ascii' / 'asciiprintable' / 'nonempty'
|
||||
listattr = 'nonempty'
|
||||
proplistattr = 'nonempty'
|
||||
stringattr = 'ascii' / 'asciiprintable' / 'nonempty'
|
||||
termattr = 'nonempty' / 'nonundefined'
|
||||
tupleattr = 'nonempty' / 'nonundefined'
|
||||
|
||||
@@ -9,15 +9,16 @@
|
||||
%% Required (except keepalive/0) callback API for UBF stateless
|
||||
%% implementations.
|
||||
-export([info/0, description/0, keepalive/0]).
|
||||
-export([moduleStart/1, moduleRestart/1]).
|
||||
-export([handlerStart/1, handlerStop/3, handlerRpc/1, handlerEvent/1]).
|
||||
|
||||
-import(ubf_plugin_handler, [sendEvent/2, install_handler/2]).
|
||||
|
||||
-compile({parse_transform,contract_parser}).
|
||||
-add_contract("ubf_bertrpc_plugin").
|
||||
-add_contract("src/ubf_bertrpc_plugin").
|
||||
|
||||
-include("ubf.hrl").
|
||||
-include("ubf_plugin_stateless.hrl").
|
||||
-include_lib("ubf/include/ubf.hrl").
|
||||
-include_lib("ubf/include/ubf_plugin_stateless.hrl").
|
||||
|
||||
info() ->
|
||||
"I am a BERT-RPC server".
|
||||
@@ -28,6 +29,14 @@ description() ->
|
||||
keepalive() ->
|
||||
ok.
|
||||
|
||||
%% @doc start module
|
||||
moduleStart(_Args) ->
|
||||
unused.
|
||||
|
||||
%% @doc restart module
|
||||
moduleRestart(Args) ->
|
||||
moduleStart(Args).
|
||||
|
||||
%% @doc start handler
|
||||
handlerStart(_Args) ->
|
||||
ack = install_handler(self(), fun handlerEvent/1),
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// -*- Doc -*-
|
||||
// vim: set syntax=asciidoc:
|
||||
|
||||
= UBF User's Guide _1st DRAFT_
|
||||
:Date: 2012/08/02
|
||||
:Revision: 0.3.7
|
||||
= UBF User's Guide
|
||||
:Date: 2012/09/02
|
||||
:Revision: 1.0.0
|
||||
:Copyright: 2012 by Joseph Wayne Norton <norton@alum.mit.edu>
|
||||
:Copyright: 2010-2011 Gemini Mobile Technologies, Inc. All rights reserved.
|
||||
:Copyright: 2002 Joe Armstrong
|
||||
@@ -299,14 +299,14 @@ The version of the contract is specified as a double-quoted string.
|
||||
|
||||
==== Types: +TYPES.
|
||||
|
||||
The UBF(b) type system has user-defined types and predefined types.
|
||||
User-defined types and predefined types are either primitive types or
|
||||
complex types.
|
||||
The UBF(b) type system has user-defined types, builtin types, and
|
||||
predefined types. All types are either primitive types or complex
|
||||
types.
|
||||
|
||||
The primitive types are Integer, Range, Float, Binary, String, Atom,
|
||||
and Reference. The complex types are Alternative, Tuple, Record,
|
||||
Extended Record, and List. User-defined "complex types" are defined
|
||||
recursively.
|
||||
Extended Record, and List. Builtin and User-defined "complex types"
|
||||
are defined recursively.
|
||||
|
||||
===== Definition: X() :: T
|
||||
|
||||
@@ -402,6 +402,50 @@ A type [X1, X2, ..., Xn] is of type [T] if all of Xi are of type T.
|
||||
Unbounded, bounded, left unbounded, and right unbounded lists are
|
||||
supported.
|
||||
|
||||
===== Builtin: B()
|
||||
|
||||
Builtin types are referenced by the notation:
|
||||
|
||||
------
|
||||
B()
|
||||
------
|
||||
|
||||
The name of the builtin type is 'B' and builtin types are of 2
|
||||
categories: +Erlang+ and +UBF+. The names used for builtin types are
|
||||
reserved and cannot be used for user-defined types.
|
||||
|
||||
Erlang builtin types are a subset of the types defined by EEP8
|
||||
<<EEP8>>. EEP8 types are used for authoring Erlang +types+ and
|
||||
+specs+ definitions.
|
||||
|
||||
|============
|
||||
| nil() | []
|
||||
| term() | any()
|
||||
| boolean() | 'false' | 'true'
|
||||
| byte() | 0..255
|
||||
| char() | 0..16#10ffff
|
||||
| non_neg_integer() | 0..
|
||||
| pos_integer() | 1..
|
||||
| neg_integer() | ..-1
|
||||
| number() | integer() | float()
|
||||
| string() | [char()]
|
||||
| nonempty_string() | [char()]+
|
||||
| module() | atom()
|
||||
| mfa() | {atom(), atom(), byte()}
|
||||
| node() | atom()
|
||||
| timeout() | 'infinity' | non_neg_integer()
|
||||
| no_return() | none()
|
||||
|
|
||||
|============
|
||||
|
||||
UBF builtin types are types particular to UBF that can be helpful for
|
||||
encoding and decoding proplists and strings.
|
||||
|
||||
|============
|
||||
| ubfproplist() | {'#P', [{term(), term()}]}
|
||||
| ubfstring() | {'#S', [byte()]}
|
||||
|============
|
||||
|
||||
===== Predefined: P() _or_ P(A1, A2, ..., An)
|
||||
|
||||
Predefined types are referenced by the notation:
|
||||
@@ -416,57 +460,48 @@ or by the notation:
|
||||
P(A1, A2, ..., An)
|
||||
------
|
||||
|
||||
The name of the predefined type is 'P'. Using the second notation,
|
||||
attributes can be specified to make the predefined type less general
|
||||
and thus more specific when matching objects.
|
||||
The name of the predefined type is 'P'. The names used for predefined
|
||||
types are reserved and cannot be used for user-defined types.
|
||||
|
||||
Using the second notation, attributes can be specified to make the
|
||||
predefined type less general and thus more specific when matching
|
||||
objects.
|
||||
|
||||
|============
|
||||
| | ascii | asciiprintable | nonempty | nonundefined
|
||||
| any | X | X | O | O
|
||||
| none | X | X | X | X
|
||||
| integer | X | X | X | X
|
||||
| float | X | X | X | X
|
||||
| binary | O | O | O | X
|
||||
| string | O | O | O | X
|
||||
| atom | O | O | O | O
|
||||
| boolean | X | X | X | X
|
||||
| tuple | X | X | O | X
|
||||
| list | X | X | O | X
|
||||
| proplist | X | X | O | X
|
||||
| term | X | X | O | O
|
||||
| none | X | X | X | X
|
||||
|============
|
||||
|
||||
The above table summarizes the set of supported predefined types and
|
||||
their respective optional attributes.
|
||||
|
||||
The "integer", "float", "binary", "string", "atom", "boolean",
|
||||
"tuple", and "list" predefined types match directly to the
|
||||
corresponding primitive or complex type.
|
||||
|
||||
The "term" predefined type matches any object.
|
||||
|
||||
The "proplist" predefined type is a specialized version of the "list"
|
||||
predefined type that matches the following types:
|
||||
|
||||
------
|
||||
[{term(), term()}]
|
||||
------
|
||||
The "any" predefined type matches any object.
|
||||
|
||||
The "none" predefined type is a placeholder to describe the return
|
||||
value of a function call that does not return to the caller.
|
||||
|
||||
The "ascii" attribute permits matches with binaries, strings, and
|
||||
atoms containing only ASCII values <<RFC20>>. Similarly, the
|
||||
The "integer", "float", "binary", "atom", "boolean", "tuple", and
|
||||
"list" predefined types match directly to the corresponding primitive
|
||||
or complex type.
|
||||
|
||||
The "ascii" attribute permits matches with binaries and atoms
|
||||
containing only ASCII values <<RFC20>>. Similarly, the
|
||||
"asciiprintable" attribute permits matches with only printable ASCII
|
||||
values.
|
||||
|
||||
The "nonempty" attribute permits matches with binaries, strings,
|
||||
atoms, tuples, lists, proplists, and terms that are of length greater
|
||||
than zero. The following objects would not be matched with the
|
||||
"nonempty" attribute:
|
||||
The "nonempty" attribute permits matches with binaries, atoms, tuples,
|
||||
lists, and any that are of length greater than zero. The following
|
||||
objects would not be matched with the "nonempty" attribute:
|
||||
|
||||
------
|
||||
<<"">>
|
||||
""
|
||||
''
|
||||
{}
|
||||
[]
|
||||
@@ -995,8 +1030,7 @@ follows:
|
||||
{\'proto', {\'ubf' | \'ebf' | \'jsf' | \'tbf' | \'ftbf' | atom()}}::
|
||||
Enable the UBF, EBF, JSF, TBF, FTBF, or an alternative protocol wire
|
||||
format. Default: \'ubf'.
|
||||
|
||||
{\'proto', {\'ubf' | \'ebf' | \'jsf' | \'tbf' | \'ftbf' | atom(), proplist()}}::
|
||||
{\'proto', {\'ubf' | \'ebf' | \'jsf' | \'tbf' | \'ftbf' | atom(), [atom() | tuple()]}}::
|
||||
Enable the UBF, EBF, JSF, TBF, FTBF, or an alternative protocol wire
|
||||
format with options. Default: {\'ubf', []}. Supported options:
|
||||
\'safe';;
|
||||
@@ -1015,7 +1049,7 @@ follows:
|
||||
Set the starting plugin, set after a client first connects to the
|
||||
server. If not set, client may select the service using the
|
||||
startSession() API. There is no default setting.
|
||||
{\'serverhello', string() | \'undefined'}::
|
||||
{\'serverhello', ubfstring() | \'undefined'}::
|
||||
Meta contract greeting string, sent when a client first connects to
|
||||
the server. If \'undefined', server hello is not sent to the
|
||||
client. Default: "meta_server".
|
||||
@@ -1063,8 +1097,8 @@ are mandatory for all stateless plugins.
|
||||
|
||||
------
|
||||
%% common callback API
|
||||
-spec info() -> string().
|
||||
-spec description() -> string().
|
||||
-spec info() -> ubfstring().
|
||||
-spec description() -> ubfstring().
|
||||
-spec handlerStop(Handler::pid(), Reason::term(), StateData::term()) ->
|
||||
NewStateData::term().
|
||||
|
||||
@@ -1128,10 +1162,10 @@ The above example also introduces three new concepts:
|
||||
|
||||
- The "?S(X)" macro definition plus other helpers are located in the
|
||||
"ubf.hrl" Erlang header file. For Erlang, the implementation of a
|
||||
UBF string is a two tuple having \'#S' as the first element and a
|
||||
list of integers as the second element. A similar technique is also
|
||||
used for the implementation of a UBF proplist (i.e. \'#P' and
|
||||
"?P(X)).
|
||||
UBF +ubfstring()+ is a two tuple having \'#S' as the first element
|
||||
and a list of bytes as the second element. A similar technique is
|
||||
also used for the implementation of a UBF +ubfproplist()+
|
||||
(i.e. \'#P' and "?P(X)).
|
||||
|
||||
=== Stateful
|
||||
|
||||
@@ -1146,8 +1180,8 @@ mandatory for all stateful plugins.
|
||||
|
||||
------
|
||||
%% common callback API
|
||||
-spec info() -> string().
|
||||
-spec description() -> string().
|
||||
-spec info() -> ubfstring().
|
||||
-spec description() -> ubfstring().
|
||||
-spec handlerStop(Handler::pid(), Reason::term(), ManagerData::term()) ->
|
||||
NewManagerData::term().
|
||||
|
||||
@@ -1257,8 +1291,37 @@ known) is returned. For TCP/IP transports, the default method is to
|
||||
connect to the specified host() and TCP ipport(). For the ETF
|
||||
transport, the alternative method is to connect to server() using the
|
||||
specified plugins(). The server() is either the process id or process
|
||||
registered name for an already-started UBF server. See <<Servers>>
|
||||
for a description of options().
|
||||
registered name for an already-started UBF server.
|
||||
|
||||
The list of supported options() are as follows:
|
||||
|
||||
{\'clientport', ipport() | {ipport(), ipport()}}::
|
||||
Specifies the TCP port to be used by the client. If tuple format, a
|
||||
port is automatically selected within the specifed range. If
|
||||
\'undefined', a random port is automatically selected. Default:
|
||||
\'undefined'.
|
||||
{\'proto', {\'ubf' | \'ebf' | \'jsf' | \'tbf' | \'ftbf' | atom()}}::
|
||||
Enable the UBF, EBF, JSF, TBF, FTBF, or an alternative protocol wire
|
||||
format. Default: \'ubf'.
|
||||
{\'proto', {\'ubf' | \'ebf' | \'jsf' | \'tbf' | \'ftbf' | atom(), [atom() | tuple()]}}::
|
||||
Enable the UBF, EBF, JSF, TBF, FTBF, or an alternative protocol wire
|
||||
format with options. Default: {\'ubf', []}. Supported options:
|
||||
\'safe';;
|
||||
Prevents decoding data that may be used to attack the Erlang
|
||||
system. In the event of receiving unsafe data, decoding fails
|
||||
with a badarg error.
|
||||
{\'startplugin', module()}::
|
||||
Set the starting plugin, set after a client first connects to the
|
||||
server. If not set, client's caller may select the service using
|
||||
the startSession() API. Default: \'undefined'.
|
||||
{\'serverhello', true | 'undefined'}::
|
||||
Meta contract greeting string, sent to a client when it first connects to
|
||||
the server. If \'undefined', client does not expect server hello to
|
||||
be sent by the server. Default: \'true'.
|
||||
{\'simplerpc', boolean()}::
|
||||
Set the simple RPC mode. If \'true', client expects only the rpc
|
||||
reply from the server. If \'false', server returns the rpc reply and next
|
||||
state to client. Default: \'false'.
|
||||
|
||||
The rpc/{2,3} functions make a synchronous call to the server.
|
||||
|
||||
@@ -1571,8 +1634,8 @@ created by making a symlink to the lang-en.conf file.
|
||||
|
||||
------
|
||||
diff -r -u 8.6.4-orig/bin/a2x.py 8.6.4/bin/a2x.py
|
||||
--- 8.6.4-orig/bin/a2x.py 2011-04-24 00:50:26.000000000 +0900
|
||||
+++ 8.6.4/bin/a2x.py 2011-04-24 00:35:55.000000000 +0900
|
||||
--- 8.6.4-orig/bin/a2x.py 2011-04-24 00:50:26.000000000 +0900
|
||||
+++ 8.6.4/bin/a2x.py 2011-04-24 00:35:55.000000000 +0900
|
||||
@@ -156,7 +156,10 @@
|
||||
def shell_copy(src, dst):
|
||||
verbose('copying "%s" to "%s"' % (src,dst))
|
||||
@@ -1675,6 +1738,9 @@ _Under Construction - To Be Updated_
|
||||
- [[[ERLANG]]] "A general-purpose programming language and runtime
|
||||
environment", http://www.erlang.org.
|
||||
|
||||
- [[[EEP8]]] "EEP 8: Types and function specifications",
|
||||
http://www.erlang.org/eeps/eep-0008.html.
|
||||
|
||||
- [[[GIT]]] "Fast Version Control System", http://git-scm.com.
|
||||
|
||||
- [[[JSFCHARSET]]] "Gemini Mobile Technologies, Inc. charset module",
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
{erl_first_files, ["src/contract_lex.erl"
|
||||
, "src/contract_yecc.erl"
|
||||
, "src/ubf_utils.erl"
|
||||
, "src/contract_parser.erl"
|
||||
, "src/ubf_types_builtin.erl"
|
||||
]}.
|
||||
|
||||
%% Erlang compiler options
|
||||
|
||||
@@ -37,7 +37,9 @@
|
||||
-include("ubf_impl.hrl").
|
||||
|
||||
-export([parse_transform/2,
|
||||
make/0, make_lex/0, make_yecc/0, preDefinedTypes/0, preDefinedTypesWithoutAttrs/0, preDefinedTypesWithAttrs/0,
|
||||
make/0, make_lex/0, make_yecc/0,
|
||||
preDefinedTypes/0, preDefinedTypesWithoutAttrs/0, preDefinedTypesWithAttrs/0,
|
||||
builtInTypes/0, builtInTypesErlang/0, builtInTypesUBF/0,
|
||||
tags/1, tags/2,
|
||||
parse_transform_contract/2,
|
||||
parse_file/1
|
||||
@@ -237,15 +239,19 @@ tags(P1, Imports) ->
|
||||
end
|
||||
end.
|
||||
|
||||
preDefinedTypes() -> preDefinedTypesWithoutAttrs() ++ preDefinedTypesWithAttrs().
|
||||
preDefinedTypes() ->
|
||||
preDefinedTypesWithoutAttrs() ++ preDefinedTypesWithAttrs().
|
||||
|
||||
preDefinedTypesWithoutAttrs() ->
|
||||
[atom, boolean, binary, float, integer, list, proplist, string, term, tuple, none].
|
||||
[any, none, atom, binary, float, integer, list, tuple].
|
||||
|
||||
preDefinedTypesWithAttrs() ->
|
||||
[
|
||||
%% any
|
||||
{any,[nonempty]}, {any,[nonundefined]}
|
||||
, {any,[nonempty,nonundefined]}
|
||||
%% atom
|
||||
{atom,[ascii]}, {atom,[asciiprintable]}, {atom,[nonempty]}, {atom,[nonundefined]}
|
||||
, {atom,[ascii]}, {atom,[asciiprintable]}, {atom,[nonempty]}, {atom,[nonundefined]}
|
||||
, {atom,[ascii,nonempty]}, {atom,[ascii,nonundefined]}, {atom,[asciiprintable,nonempty]}, {atom,[asciiprintable,nonundefined]}
|
||||
, {atom,[ascii,nonempty,nonundefined]}, {atom,[asciiprintable,nonempty,nonundefined]}
|
||||
, {atom,[nonempty,nonundefined]}
|
||||
@@ -254,18 +260,19 @@ preDefinedTypesWithAttrs() ->
|
||||
, {binary,[ascii,nonempty]}, {binary,[asciiprintable,nonempty]}
|
||||
%% list
|
||||
, {list,[nonempty]}
|
||||
%% proplist
|
||||
, {proplist,[nonempty]}
|
||||
%% string
|
||||
, {string,[ascii]}, {string,[asciiprintable]}, {string,[nonempty]}
|
||||
, {string,[ascii,nonempty]}, {string,[asciiprintable,nonempty]}
|
||||
%% term
|
||||
, {term,[nonempty]}, {term,[nonundefined]}
|
||||
, {term,[nonempty,nonundefined]}
|
||||
%% tuple
|
||||
, {tuple,[nonempty]}
|
||||
].
|
||||
|
||||
builtInTypes() ->
|
||||
builtInTypesErlang() ++ builtInTypesUBF().
|
||||
|
||||
builtInTypesErlang() ->
|
||||
[nil, term, boolean, byte, char, non_neg_integer, pos_integer, neg_integer, number, string, nonempty_string, module, mfa, node, timeout, no_return].
|
||||
|
||||
builtInTypesUBF() ->
|
||||
[ubfproplist, ubfstring].
|
||||
|
||||
pass2(P, Imports) ->
|
||||
Name = require(one, name, P),
|
||||
Vsn = require(one, vsn, P),
|
||||
@@ -273,6 +280,8 @@ pass2(P, Imports) ->
|
||||
Any = require(zero_or_one, anystate, P),
|
||||
Trans = require(many, transition, P),
|
||||
|
||||
AllImports = if Name =/= "ubf_types_builtin" -> [ubf_types_builtin|Imports]; true -> Imports end,
|
||||
|
||||
ImportTypes = lists:flatten(
|
||||
[
|
||||
begin
|
||||
@@ -294,7 +303,7 @@ pass2(P, Imports) ->
|
||||
[ begin {TDef, TTag} = Mod:contract_type(T), {T, TDef, TTag} end
|
||||
|| T <- TL ]
|
||||
end
|
||||
|| Import <- Imports ]
|
||||
|| Import <- AllImports ]
|
||||
),
|
||||
ImportTypeNames = [ T || {T, _, _} <- ImportTypes ],
|
||||
|
||||
|
||||
@@ -188,11 +188,11 @@ rec_ext(Name, Args) ->
|
||||
if Types == [] ->
|
||||
[{atom,Name},
|
||||
{atom,undefined},
|
||||
{predef,term}];
|
||||
{predef,any}];
|
||||
true ->
|
||||
[{atom,Name},
|
||||
eor({atom,undefined}, {tuple, [ {atom,X} || X <- Fields ]}),
|
||||
{predef,term}|Types]
|
||||
{predef,any}|Types]
|
||||
end),
|
||||
{record_ext, Name, Fields, Defaults, Types1}.
|
||||
|
||||
|
||||
@@ -89,6 +89,8 @@ checkEventIn(Msg, ThisState, Mod) ->
|
||||
%%----------------------------------------------------------------------
|
||||
%% Check type attribute
|
||||
|
||||
isTypeAttr(any,nonempty) -> true;
|
||||
isTypeAttr(any,nonundefined) -> true;
|
||||
isTypeAttr(atom,ascii) -> true;
|
||||
isTypeAttr(atom,asciiprintable) -> true;
|
||||
isTypeAttr(atom,nonempty) -> true;
|
||||
@@ -97,12 +99,6 @@ isTypeAttr(binary,ascii) -> true;
|
||||
isTypeAttr(binary,asciiprintable) -> true;
|
||||
isTypeAttr(binary,nonempty) -> true;
|
||||
isTypeAttr(list,nonempty) -> true;
|
||||
isTypeAttr(proplist,nonempty) -> true;
|
||||
isTypeAttr(string,ascii) -> true;
|
||||
isTypeAttr(string,asciiprintable) -> true;
|
||||
isTypeAttr(string,nonempty) -> true;
|
||||
isTypeAttr(term,nonempty) -> true;
|
||||
isTypeAttr(term,nonundefined) -> true;
|
||||
isTypeAttr(tuple,nonempty) -> true;
|
||||
isTypeAttr(_,_) -> false.
|
||||
|
||||
@@ -241,13 +237,6 @@ check_term({atom, Y}=_Check, X, _Level, _Mod) ->
|
||||
true ->
|
||||
?FAIL({Check,X})
|
||||
end;
|
||||
%% boolean
|
||||
check_term({boolean, Y}=_Check, X, _Level, _Mod) ->
|
||||
if Y =:= X andalso is_boolean(Y) ->
|
||||
true;
|
||||
true ->
|
||||
?FAIL({Check,X})
|
||||
end;
|
||||
%% binary
|
||||
check_term({binary, Y}=_Check, X, _Level, _Mod) ->
|
||||
if Y =:= X andalso is_binary(Y) ->
|
||||
@@ -269,13 +258,6 @@ check_term({integer, Y}=_Check, X, _Level, _Mod) ->
|
||||
true ->
|
||||
?FAIL({Check,X})
|
||||
end;
|
||||
%% string
|
||||
check_term({string, {'#S', Y0}=Y}=_Check, X, _Level, _Mod) ->
|
||||
if Y =:= X andalso is_list(Y0) ->
|
||||
true;
|
||||
true ->
|
||||
?FAIL({Check,X})
|
||||
end;
|
||||
%% predef
|
||||
check_term({predef, Args}=_Check, X, _Level, _Mod) ->
|
||||
case check_term_predef(Args, X) of
|
||||
@@ -335,10 +317,12 @@ check_term_range(Min, Max, X) ->
|
||||
|
||||
|
||||
%% check_term_predef
|
||||
check_term_predef(any, _X) ->
|
||||
true;
|
||||
check_term_predef(none, _X) ->
|
||||
true;
|
||||
check_term_predef(atom, X) ->
|
||||
is_atom(X);
|
||||
check_term_predef(boolean, X) ->
|
||||
is_boolean(X);
|
||||
check_term_predef(binary, X) ->
|
||||
is_binary(X);
|
||||
check_term_predef(float, X) ->
|
||||
@@ -347,54 +331,19 @@ check_term_predef(integer, X) ->
|
||||
is_integer(X);
|
||||
check_term_predef(list, X) ->
|
||||
is_list(X);
|
||||
check_term_predef(proplist, X) ->
|
||||
case X of
|
||||
{'#P', Y} when is_list(Y) ->
|
||||
is_proplist(Y);
|
||||
_ ->
|
||||
false
|
||||
end;
|
||||
check_term_predef(string, X) ->
|
||||
case X of
|
||||
{'#S', Y} when is_list(Y) ->
|
||||
is_string(Y);
|
||||
_ ->
|
||||
false
|
||||
end;
|
||||
check_term_predef(term, _X) ->
|
||||
true;
|
||||
check_term_predef(tuple, X) ->
|
||||
is_tuple(X);
|
||||
check_term_predef(none, _X) ->
|
||||
true;
|
||||
check_term_predef({any,Attrs}, X) ->
|
||||
check_term_attrlist(any,Attrs,X);
|
||||
check_term_predef({atom,Attrs}, X) ->
|
||||
is_atom(X) andalso check_term_attrlist(atom,Attrs,X);
|
||||
check_term_predef({boolean,Attrs}, X) ->
|
||||
is_boolean(X) andalso check_term_attrlist(boolean,Attrs,X);
|
||||
check_term_predef({binary,Attrs}, X) ->
|
||||
is_binary(X) andalso check_term_attrlist(binary,Attrs,X);
|
||||
check_term_predef({list,Attrs}, X) ->
|
||||
is_list(X) andalso check_term_attrlist(list,Attrs,X);
|
||||
check_term_predef({proplist,Attrs}, X) ->
|
||||
case X of
|
||||
{'#P', Y} when is_list(Y) ->
|
||||
is_proplist(Y) andalso check_term_attrlist(proplist,Attrs,X);
|
||||
_ ->
|
||||
false
|
||||
end;
|
||||
check_term_predef({string,Attrs}, X) ->
|
||||
case X of
|
||||
{'#S', Y} when is_list(Y) ->
|
||||
is_string(Y) andalso check_term_attrlist(string,Attrs,X);
|
||||
_ ->
|
||||
false
|
||||
end;
|
||||
check_term_predef({term,Attrs}, X) ->
|
||||
check_term_attrlist(term,Attrs,X);
|
||||
check_term_predef({tuple,Attrs}, X) ->
|
||||
is_tuple(X) andalso check_term_attrlist(tuple,Attrs,X).
|
||||
|
||||
|
||||
%% check_term_attrlist
|
||||
check_term_attrlist(Type, Attrs, Val) ->
|
||||
[] == [ {Type,Attr,Val} || Attr <- Attrs, not check_term_attr(Type,Attr,Val) ].
|
||||
@@ -412,21 +361,6 @@ check_term_attr(Type,nonundefined,Val) ->
|
||||
check_term_attr(_,_,_) ->
|
||||
false.
|
||||
|
||||
|
||||
%% is_string
|
||||
is_string([H|T]) when is_integer(H), H < 256, H > -1 ->
|
||||
is_string(T);
|
||||
is_string([]) -> true;
|
||||
is_string(_) -> false.
|
||||
|
||||
|
||||
%% is_proplist
|
||||
is_proplist([P|T]) when tuple_size(P) =:= 2 ->
|
||||
is_proplist(T);
|
||||
is_proplist([]) -> true;
|
||||
is_proplist(_) -> false.
|
||||
|
||||
|
||||
%% is_ascii
|
||||
is_ascii(A) when is_atom(A) ->
|
||||
is_ascii(atom_to_list(A));
|
||||
|
||||
@@ -109,9 +109,6 @@ type1(_Gen,{range,Lo,Hi}) ->
|
||||
%% atom
|
||||
type1(_Gen,{atom,Value}) when is_atom(Value) ->
|
||||
Value;
|
||||
%% boolean
|
||||
type1(_Gen,{boolean,Value}) when is_boolean(Value) ->
|
||||
Value;
|
||||
%% binary
|
||||
type1(_Gen,{binary,Value}) when is_binary(Value) ->
|
||||
Value;
|
||||
@@ -125,10 +122,13 @@ type1(_Gen,{integer,Value}) when is_integer(Value) ->
|
||||
type1(_Gen,{string,Value}) when is_list(Value) ->
|
||||
Value;
|
||||
%% predef
|
||||
type1(_Gen,{predef,any}) ->
|
||||
qc_gen:qc_term();
|
||||
type1(_Gen,{predef,none}) ->
|
||||
%% not supported
|
||||
exit(fatal);
|
||||
type1(_Gen,{predef,atom}) ->
|
||||
qc_gen:qc_atom();
|
||||
type1(_Gen,{predef,boolean}) ->
|
||||
bool();
|
||||
type1(_Gen,{predef,integer}) ->
|
||||
oneof([int(),largeint()]);
|
||||
type1(_Gen,{predef,float}) ->
|
||||
@@ -137,30 +137,17 @@ type1(_Gen,{predef,binary}) ->
|
||||
qc_gen:qc_binary();
|
||||
type1(_Gen,{predef,list}) ->
|
||||
qc_gen:qc_list();
|
||||
type1(_Gen,{predef,proplist}) ->
|
||||
?P(qc_gen:qc_proplist());
|
||||
type1(_Gen,{predef,string}) ->
|
||||
?S(qc_gen:qc_string());
|
||||
type1(_Gen,{predef,tuple}) ->
|
||||
qc_gen:qc_tuple();
|
||||
type1(_Gen,{predef,term}) ->
|
||||
qc_gen:qc_term();
|
||||
type1(_Gen,{predef,none}) ->
|
||||
%% not supported
|
||||
exit(fatal);
|
||||
%% predef with attributes
|
||||
type1(_Gen,{predef,{any,Attrs}}) ->
|
||||
qc_gen:qc_term(Attrs);
|
||||
type1(_Gen,{predef,{atom,Attrs}}) ->
|
||||
qc_gen:qc_atom(Attrs);
|
||||
type1(_Gen,{predef,{binary,Attrs}}) ->
|
||||
qc_gen:qc_binary(Attrs);
|
||||
type1(_Gen,{predef,{list,Attrs}}) ->
|
||||
qc_gen:qc_list(Attrs);
|
||||
type1(_Gen,{predef,{proplist,Attrs}}) ->
|
||||
?P(qc_gen:qc_proplist(Attrs));
|
||||
type1(_Gen,{predef,{string,Attrs}}) ->
|
||||
?S(qc_gen:qc_string(Attrs));
|
||||
type1(_Gen,{predef,{term,Attrs}}) ->
|
||||
qc_gen:qc_term(Attrs);
|
||||
type1(_Gen,{predef,{tuple,Attrs}}) ->
|
||||
qc_gen:qc_tuple(Attrs);
|
||||
%% abnf
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
{modules, [contract_parser
|
||||
, contract_lex
|
||||
, contract_yecc
|
||||
, ubf_types_builtin
|
||||
, ubf_client
|
||||
, ubf_server
|
||||
, ubf_plugin_handler
|
||||
|
||||
@@ -234,7 +234,7 @@ ubf_client(Parent, Plugins, Server, Options, Timeout)
|
||||
when is_list(Plugins) andalso length(Plugins) > 0 andalso is_pid(Server) andalso is_list(Options) ->
|
||||
process_flag(trap_exit, true),
|
||||
Driver = ubf_server:start_term_listener(Server, Plugins, Options),
|
||||
ServerHello = proplists:get_value(serverhello, Options, defined),
|
||||
ServerHello = proplists:get_value(serverhello, Options, true),
|
||||
SimpleRPC = proplists:get_value(simplerpc, Options, false),
|
||||
if ServerHello =/= undefined ->
|
||||
%% wait for a startup message
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
+NAME("meta_server").
|
||||
|
||||
+VSN("ubf1.0").
|
||||
+VSN("ubf2.0").
|
||||
|
||||
+TYPES
|
||||
|
||||
@@ -33,11 +33,11 @@ info() :: info;
|
||||
description() :: description;
|
||||
services() :: services;
|
||||
contract() :: contract;
|
||||
serviceList() :: [string()] "Names of the offered services";
|
||||
serviceList() :: [ubfstring()] "Names of the offered services";
|
||||
|
||||
help() :: help;
|
||||
restartService() :: {restartService, string(), term()};
|
||||
startSession() :: {startSession, string(), term()};
|
||||
restartService() :: {restartService, ubfstring(), term()};
|
||||
startSession() :: {startSession, ubfstring(), term()};
|
||||
ok() :: {ok, term()};
|
||||
error() :: {error, term()};
|
||||
ok_or_error() :: ok() | error().
|
||||
|
||||
@@ -104,7 +104,7 @@ start(Name, Plugins, Port) ->
|
||||
%% - +{proto, {ubf | ebf | atom()}}+ Enable the UBF, EBF, or
|
||||
%% an alternative protocol wire format.
|
||||
%% Default: ubf.
|
||||
%% - +{proto, {ubf | ebf | atom(), proplist()}}+ Enable the UBF,
|
||||
%% - +{proto, {ubf | ebf | atom(), [atom() | tuple()]}}+ Enable the UBF,
|
||||
%% EBF, or an alternative protocol wire format with options.
|
||||
%% Default: +{ubf, []}+.
|
||||
%%
|
||||
@@ -125,7 +125,7 @@ start(Name, Plugins, Port) ->
|
||||
%% client first connects to the server. If not set, client may
|
||||
%% select the service using the startSession() API. There is
|
||||
%% no default setting.
|
||||
%% - +{serverhello, string() | undefined}+ Meta contract greeting
|
||||
%% - +{serverhello, ubfstring() | undefined}+ Meta contract greeting
|
||||
%% string, sent when a client first connects to the server. If
|
||||
%% undefined, server hello is not sent to the client.
|
||||
%% Default: "meta_server".
|
||||
|
||||
124
src/ubf_types_builtin.con
Normal file
124
src/ubf_types_builtin.con
Normal file
@@ -0,0 +1,124 @@
|
||||
%%% -*- mode: erlang -*-
|
||||
%%%
|
||||
|
||||
+NAME("ubf_types_builtin").
|
||||
|
||||
+VSN("ubf2.0").
|
||||
|
||||
|
||||
%%
|
||||
%% Excerpt from http://www.erlang.org/eeps/eep-0008.html
|
||||
%%
|
||||
%% For convenience, the following types are also built-in. They can be
|
||||
%% thought as predefined aliases for the type unions also shown in the
|
||||
%% table. (Some type unions below slightly abuse the syntax of types.)
|
||||
%%
|
||||
%% ========================== =====================================
|
||||
%% Built-in type Stands for
|
||||
%% ========================== =====================================
|
||||
%% ``term()`` ``any()``
|
||||
%% ``boolean()`` ``'false' | 'true'``
|
||||
%% ``byte()`` ``0..255``
|
||||
%% ``char()`` ``0..16#10ffff``
|
||||
%% ``non_neg_integer()`` ``0..``
|
||||
%% ``pos_integer()`` ``1..``
|
||||
%% ``neg_integer()`` ``..-1``
|
||||
%% ``number()`` ``integer() | float()``
|
||||
%% ``list()`` ``[any()]``
|
||||
%% ``maybe_improper_list()`` ``maybe_improper_list(any(), any())``
|
||||
%% ``maybe_improper_list(T)`` ``maybe_improper_list(T, any())``
|
||||
%% ``string()`` ``[char()]``
|
||||
%% ``nonempty_string()`` ``[char(),...]``
|
||||
%% ``iolist()`` ``maybe_improper_list(``
|
||||
%% ``char() | binary() |``
|
||||
%% ``iolist(), binary() | [])``
|
||||
%% ``module()`` ``atom()``
|
||||
%% ``mfa()`` ``{atom(),atom(),byte()}``
|
||||
%% ``node()`` ``atom()``
|
||||
%% ``timeout()`` ``'infinity' | non_neg_integer()``
|
||||
%% ``no_return()`` ``none()``
|
||||
%% ========================== =====================================
|
||||
%%
|
||||
%% Users are not allowed to define types with the same names as the
|
||||
%% predefined or built-in ones. This is checked by the compiler and
|
||||
%% its violation results in a compilation error. (For bootstrapping
|
||||
%% purposes, it can also result to just a warning if this involves a
|
||||
%% built-in type which has just been introduced.)
|
||||
%%
|
||||
%% *NOTE*: The following built-in list types also exist, but they are
|
||||
%% expected to be rarely used. Hence, they have long names:
|
||||
%%
|
||||
%% ::
|
||||
%%
|
||||
%% nonempty_maybe_improper_list(Type) :: nonempty_maybe_improper_list(Type, any())
|
||||
%% nonempty_maybe_improper_list() :: nonempty_maybe_improper_list(any())
|
||||
%%
|
||||
%% where the following two types
|
||||
%%
|
||||
%% ::
|
||||
%%
|
||||
%% nonempty_improper_list(Type1, Type2)
|
||||
%% nonempty_maybe_improper_list(Type1, Type2)
|
||||
%%
|
||||
%% define the set of Erlang terms one would expect.
|
||||
%%
|
||||
|
||||
|
||||
%%
|
||||
%% Supported eep8 predefined types:
|
||||
%%
|
||||
%% via ubf predefined types
|
||||
%% - any()
|
||||
%% - none()
|
||||
%% - list()
|
||||
%%
|
||||
%% via ubf contract
|
||||
%% - nil()
|
||||
%% - term()
|
||||
%% - byte()
|
||||
%% - char()
|
||||
%% - non_neg_integer()
|
||||
%% - pos_integer()
|
||||
%% - neg_integer()
|
||||
%% - number()
|
||||
%% - string()
|
||||
%% - nonempty_string()
|
||||
%% - module()
|
||||
%% - mfa()
|
||||
%% - node()
|
||||
%% - timeout()
|
||||
%% - no_return()
|
||||
%%
|
||||
%% not implemented
|
||||
%% - iolist()
|
||||
%% - maybe_improper_list()
|
||||
%% - maybe_improper_list(T)
|
||||
%% - nonempty_maybe_improper_list()
|
||||
%% - nonempty_maybe_improper_list(T)
|
||||
%%
|
||||
|
||||
|
||||
%%%%%%
|
||||
+TYPES
|
||||
|
||||
%% Erlang built-in types
|
||||
nil() :: [];
|
||||
term() :: any();
|
||||
boolean() :: 'false' | 'true';
|
||||
byte() :: 0..255;
|
||||
char() :: 0..16#10ffff;
|
||||
non_neg_integer() :: 0..;
|
||||
pos_integer() :: 1..;
|
||||
neg_integer() :: ..-1;
|
||||
number() :: integer() | float();
|
||||
string() :: [char()];
|
||||
nonempty_string() :: [char()]+;
|
||||
module() :: atom();
|
||||
mfa() :: {atom(), atom(), byte()};
|
||||
node() :: atom();
|
||||
timeout() :: 'infinity' | non_neg_integer();
|
||||
no_return() :: none();
|
||||
|
||||
%% UBF built-in types
|
||||
ubfproplist() :: {'#P', [{term(), term()}]};
|
||||
ubfstring() :: {'#S', [byte()]}.
|
||||
12
src/ubf_types_builtin.erl
Normal file
12
src/ubf_types_builtin.erl
Normal file
@@ -0,0 +1,12 @@
|
||||
%%%
|
||||
|
||||
%%% @doc UBF TYPES builtin types
|
||||
%%%
|
||||
%%% @end
|
||||
%%%
|
||||
|
||||
-module(ubf_types_builtin).
|
||||
|
||||
%% NOTE the following three lines
|
||||
-compile({parse_transform,contract_parser}).
|
||||
-add_contract("src/ubf_types_builtin").
|
||||
@@ -77,12 +77,15 @@ ubf_contract2(C) ->
|
||||
, "% false\n%\t\tfalse"
|
||||
, "% undefined\n%\t\tundefined"
|
||||
, "%"
|
||||
, "% any()\n%\t\tany"
|
||||
, "% any()?\n%\t\tany | undefined"
|
||||
, "%"
|
||||
, "% none()\n%\t\t /* no result is returned */"
|
||||
, "% none()?\n%\t\t /* no result is returned */ | undefined"
|
||||
, "%"
|
||||
, "% atom()\n%\t\tatom"
|
||||
, "% atom()?\n%\t\tatom | undefined"
|
||||
, "%"
|
||||
, "% boolean()\n%\t\tboolean"
|
||||
, "% boolean()?\n%\t\tboolean | undefined"
|
||||
, "%"
|
||||
, "% binary()\n%\t\tbinary"
|
||||
, "% binary()?\n%\t\tbinary | undefined"
|
||||
, "%"
|
||||
@@ -95,25 +98,16 @@ ubf_contract2(C) ->
|
||||
, "% list()\n%\t\tlist"
|
||||
, "% list()?\n%\t\tlist | undefined"
|
||||
, "%"
|
||||
, "% proplist()\n%\t\t{'#P',proplist}"
|
||||
, "% proplist()?\n%\t\t{'#P',proplist} | undefined"
|
||||
, "%"
|
||||
, "% string()\n%\t\t{'#S',string}"
|
||||
, "% string()?\n%\t\t{'#S',string} | undefined"
|
||||
, "%"
|
||||
, "% term()\n%\t\tterm"
|
||||
, "% term()?\n%\t\tterm | undefined"
|
||||
, "%"
|
||||
, "% tuple()\n%\t\ttuple"
|
||||
, "% tuple()?\n%\t\ttuple | undefined"
|
||||
, "%"
|
||||
, "% none()\n%\t\t /* no result is returned */"
|
||||
, "% none()?\n%\t\t /* no result is returned */ | undefined"
|
||||
, "%"
|
||||
, "%% --------------------"
|
||||
, "%% type attributes"
|
||||
, "%%"
|
||||
, "%"
|
||||
, "% any(AnyAttrs)\n%\t\tany"
|
||||
, "% any(AnyAttrs)?\n%\t\tany | undefined"
|
||||
, "%"
|
||||
, "% atom(AtomAttrs)\n%\t\tatom"
|
||||
, "% atom(AtomAttrs)?\n%\t\tatom | undefined"
|
||||
, "%"
|
||||
@@ -123,17 +117,13 @@ ubf_contract2(C) ->
|
||||
, "% list(ListAttrs)\n%\t\tlist"
|
||||
, "% list(ListAttrs)?\n%\t\tlist | undefined"
|
||||
, "%"
|
||||
, "% proplist(PropListAttrs)\n%\t\t{'#P',proplist}"
|
||||
, "% proplist(PropListAttrs)?\n%\t\t{'#P',proplist} | undefined"
|
||||
, "%"
|
||||
, "% string(StringAttrs)\n%\t\t{'#S',string}"
|
||||
, "% string(StringAttrs)?\n%\t\t{'#S',string} | undefined"
|
||||
, "%"
|
||||
, "% tuple(TupleAttrs)\n%\t\ttuple"
|
||||
, "% tuple(TupleAttrs)?\n%\t\ttuple | undefined"
|
||||
, "%"
|
||||
, "% term(TermAttrs)\n%\t\tterm"
|
||||
, "% term(TermAttrs)?\n%\t\tterm | undefined"
|
||||
, "%"
|
||||
, "% AnyAttrs"
|
||||
, "% \t nonempty"
|
||||
, "% \t nonundefined"
|
||||
, "%"
|
||||
, "% AtomAttrs"
|
||||
, "% \t ascii | asciiprintable"
|
||||
@@ -147,17 +137,6 @@ ubf_contract2(C) ->
|
||||
, "% ListAttrs"
|
||||
, "% \t nonempty"
|
||||
, "%"
|
||||
, "% PropListAttrs"
|
||||
, "% \t nonempty"
|
||||
, "%"
|
||||
, "% StringAttrs"
|
||||
, "% \t ascii | asciiprintable"
|
||||
, "% \t nonempty"
|
||||
, "%"
|
||||
, "% TermAttrs"
|
||||
, "% \t nonempty"
|
||||
, "% \t nonundefined"
|
||||
, "%"
|
||||
, "% TupleAttrs"
|
||||
, "% \t nonempty"
|
||||
, "%"
|
||||
@@ -366,9 +345,6 @@ typeref(_Style,{range,Lo,Hi},_C) ->
|
||||
%% atom
|
||||
typeref(_Style,{atom,Value},_C) ->
|
||||
io_lib:format("~p", [Value]);
|
||||
%% boolean
|
||||
typeref(_Style,{boolean,Value},_C) ->
|
||||
io_lib:format("~p", [Value]);
|
||||
%% binary
|
||||
typeref(_Style,{binary,Value},_C) ->
|
||||
io_lib:format("~p", [Value]);
|
||||
@@ -382,10 +358,12 @@ typeref(_Style,{integer,Value},_C) ->
|
||||
typeref(_Style,{string,Value},_C) ->
|
||||
io_lib:format("~p", [Value]);
|
||||
%% predef
|
||||
typeref(_Style,{predef,any},_C) ->
|
||||
"any()";
|
||||
typeref(_Style,{predef,none},_C) ->
|
||||
"none()";
|
||||
typeref(_Style,{predef,atom},_C) ->
|
||||
"atom()";
|
||||
typeref(_Style,{predef,boolean},_C) ->
|
||||
"boolean()";
|
||||
typeref(_Style,{predef,binary},_C) ->
|
||||
"binary()";
|
||||
typeref(_Style,{predef,float},_C) ->
|
||||
@@ -394,31 +372,17 @@ typeref(_Style,{predef,integer},_C) ->
|
||||
"integer()";
|
||||
typeref(_Style,{predef,list},_C) ->
|
||||
"list()";
|
||||
typeref(_Style,{predef,proplist},_C) ->
|
||||
"proplist()";
|
||||
typeref(_Style,{predef,string},_C) ->
|
||||
"string()";
|
||||
typeref(_Style,{predef,term},_C) ->
|
||||
"term()";
|
||||
typeref(_Style,{predef,tuple},_C) ->
|
||||
"tuple()";
|
||||
typeref(_Style,{predef,none},_C) ->
|
||||
"none()";
|
||||
%% predef with attributes
|
||||
typeref(_Style,{predef,{any,Attrs}},_C) ->
|
||||
io_lib:format("any(~s)", [join([ atom_to_list(Attr) || Attr <- Attrs ], ",")]);
|
||||
typeref(_Style,{predef,{atom,Attrs}},_C) ->
|
||||
io_lib:format("atom(~s)", [join([ atom_to_list(Attr) || Attr <- Attrs ], ",")]);
|
||||
typeref(_Style,{predef,{boolean,Attrs}},_C) ->
|
||||
io_lib:format("boolean(~s)", [join([ atom_to_list(Attr) || Attr <- Attrs ], ",")]);
|
||||
typeref(_Style,{predef,{binary,Attrs}},_C) ->
|
||||
io_lib:format("binary(~s)", [join([ atom_to_list(Attr) || Attr <- Attrs ], ",")]);
|
||||
typeref(_Style,{predef,{list,Attrs}},_C) ->
|
||||
io_lib:format("list(~s)", [join([ atom_to_list(Attr) || Attr <- Attrs ], ",")]);
|
||||
typeref(_Style,{predef,{proplist,Attrs}},_C) ->
|
||||
io_lib:format("proplist(~s)", [join([ atom_to_list(Attr) || Attr <- Attrs ], ",")]);
|
||||
typeref(_Style,{predef,{string,Attrs}},_C) ->
|
||||
io_lib:format("string(~s)", [join([ atom_to_list(Attr) || Attr <- Attrs ], ",")]);
|
||||
typeref(_Style,{predef,{term,Attrs}},_C) ->
|
||||
io_lib:format("term(~s)", [join([ atom_to_list(Attr) || Attr <- Attrs ], ",")]);
|
||||
typeref(_Style,{predef,{tuple,Attrs}},_C) ->
|
||||
io_lib:format("tuple(~s)", [join([ atom_to_list(Attr) || Attr <- Attrs ], ",")]);
|
||||
%% otherwise
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
+NAME("test").
|
||||
|
||||
+VSN("ubf1.0").
|
||||
+VSN("ubf2.0").
|
||||
|
||||
%%%%%
|
||||
%%% states
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
+NAME("test").
|
||||
|
||||
+VSN("ubf1.0").
|
||||
+VSN("ubf2.0").
|
||||
|
||||
|
||||
%%%%%
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
+NAME("types").
|
||||
|
||||
+VSN("ubf1.0").
|
||||
+VSN("ubf2.0").
|
||||
|
||||
%%%%%%
|
||||
+TYPES
|
||||
@@ -33,11 +33,9 @@
|
||||
|
||||
%%%%%
|
||||
%%% well-known primitives
|
||||
bool() :: true | false;
|
||||
expires() :: {integer(), integer(), integer()}; %% erlang-style timestamp
|
||||
opaque() :: binary();
|
||||
time_t() :: integer();
|
||||
timeout() :: infinity | integer(); %% milliseconds
|
||||
timeout_or_expires() :: timeout() | expires();
|
||||
ts() :: integer();
|
||||
utf8() :: binary();
|
||||
@@ -84,10 +82,10 @@ ubf_keepalive_res() :: ok;
|
||||
%%%%%
|
||||
%%% meta methods
|
||||
ubf_info_req() :: info;
|
||||
ubf_info_res() :: string();
|
||||
ubf_info_res() :: ubfstring();
|
||||
|
||||
ubf_description_req() :: description;
|
||||
ubf_description_res() :: string();
|
||||
ubf_description_res() :: ubfstring();
|
||||
|
||||
ubf_contract_req() :: contract;
|
||||
ubf_contract_res() :: term().
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
+NAME("file_server").
|
||||
|
||||
+VSN("ubf1.0").
|
||||
+VSN("ubf2.0").
|
||||
|
||||
+TYPES
|
||||
|
||||
@@ -33,7 +33,7 @@ info() :: info;
|
||||
description() :: description;
|
||||
contract() :: contract;
|
||||
|
||||
file() :: string();
|
||||
file() :: ubfstring();
|
||||
ls() :: ls;
|
||||
files() :: {files, [file()]};
|
||||
getFile() :: {get, file()};
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
+NAME("irc").
|
||||
|
||||
+VSN("ubf1.0").
|
||||
+VSN("ubf2.0").
|
||||
|
||||
+TYPES
|
||||
info() :: info;
|
||||
@@ -34,10 +34,10 @@ contract() :: contract;
|
||||
|
||||
ok() :: ok;
|
||||
bool() :: true | false;
|
||||
nick() :: string();
|
||||
nick() :: ubfstring();
|
||||
oldnick() :: nick();
|
||||
newnick() :: nick();
|
||||
group() :: string();
|
||||
group() :: ubfstring();
|
||||
groups() :: [group()];
|
||||
|
||||
logon() :: logon;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
+NAME("test").
|
||||
|
||||
+VSN("ubf1.0").
|
||||
+VSN("ubf2.0").
|
||||
|
||||
+TYPES
|
||||
|
||||
@@ -33,27 +33,25 @@ info() :: info;
|
||||
description() :: description;
|
||||
services() :: services;
|
||||
contract() :: contract;
|
||||
serviceList() :: [string()];
|
||||
serviceList() :: [ubfstring()];
|
||||
|
||||
dummy() :: {dummy, dummyrecord()};
|
||||
dummyrecord() :: #dummyrecord{foo::integer(), bar::binary()};
|
||||
dummy1a() :: atom(ascii,nonempty,nonundefined);
|
||||
dummy1b() :: atom(asciiprintable,nonempty,nonundefined);
|
||||
dummy2a() :: string(ascii,nonempty);
|
||||
dummy2b() :: string(asciiprintable,nonempty);
|
||||
dummy3a() :: binary(ascii,nonempty);
|
||||
dummy3b() :: binary(asciiprintable,nonempty);
|
||||
dummy4() :: term(nonempty,nonundefined);
|
||||
dummy4() :: any(nonempty,nonundefined);
|
||||
dummy5() :: #dummy5{hoge1::1, hoge2::two, hoge3::3.0, hoge4::<<"4">>};
|
||||
|
||||
password() :: string();
|
||||
file() :: string();
|
||||
password() :: ubfstring();
|
||||
file() :: ubfstring();
|
||||
noSuchFile() :: {error, noSuchFile};
|
||||
doubleInt() :: [integer()];
|
||||
upCase() :: string();
|
||||
upCase() :: ubfstring();
|
||||
logon() :: {logon, password()};
|
||||
ls() :: ls;
|
||||
files() :: {files, [string()]} "request a list of file";
|
||||
files() :: {files, [ubfstring()]} "request a list of file";
|
||||
callback() :: {callback, none()};
|
||||
getFile() :: {get, file()};
|
||||
okFile() :: {ok, binary()};
|
||||
@@ -63,7 +61,7 @@ ack() :: ack;
|
||||
error() :: error;
|
||||
ok() :: ok;
|
||||
intList() :: [integer()];
|
||||
propList() :: proplist();
|
||||
propList() :: ubfproplist();
|
||||
testAmbiguities() :: testAmbiguities;
|
||||
foo() :: #foo{attribute1::term()};
|
||||
callbackOnItsWay() :: callbackOnItsWay.
|
||||
@@ -83,7 +81,7 @@ callbackOnItsWay() :: callbackOnItsWay.
|
||||
EVENT <= callback().
|
||||
|
||||
+STATE funny
|
||||
string() => upCase() & funny;
|
||||
ubfstring() => upCase() & funny;
|
||||
intList() => doubleInt() & funny;
|
||||
propList() => propList() & funny;
|
||||
stop() => ack() & start.
|
||||
@@ -92,14 +90,12 @@ callbackOnItsWay() :: callbackOnItsWay.
|
||||
dummy() => dummy();
|
||||
dummy1a() => dummy1a();
|
||||
dummy1b() => dummy1b();
|
||||
dummy2a() => dummy2a();
|
||||
dummy2b() => dummy2b();
|
||||
dummy3a() => dummy3a();
|
||||
dummy3b() => dummy3b();
|
||||
dummy4() => dummy4();
|
||||
dummy5() => dummy5();
|
||||
foo() => term();
|
||||
info() => string();
|
||||
description() => string();
|
||||
info() => ubfstring();
|
||||
description() => ubfstring();
|
||||
services() => serviceList();
|
||||
contract() => term().
|
||||
|
||||
Reference in New Issue
Block a user