예제 #1
0
int read_global(
    )
{
/**
Function: Reads file in global state
Inputs: File descriptor
Returns: IF reaches end of file, -1
         ELSE 0
Procedure:
1. DO
        IF token is '::='
            Return IN_DEFINITION
        ELSE IF token is DEFINITIONS
            WHILE next token is not '::='
                IF token is IMPLICIT, clear implicit flag for file
                ELSE IF token is EXPLICIT, set explicit flag for file
                ELSE IF token is not TAGS, error
        ELSE IF token is EXPORTS OR IMPORTS, throw away everything up to ';'
        ELSE IF haven't a classname, copy token into classname
2. WHILE have another token
   Return -1
**/
    do
    {
        if (*token == ':')
        {
            get_known(0, &token[1], colon_ch);
            get_known(0, &token[2], equal_ch);
            token[3] = 0;
            max = min = 0;
            state = IN_DEFINITION;
            return 0;
        }
        else if (!strcmp(token, definitions_w))
        {
            while (get_token(0, token) && *token != ':')
            {
                if (!strcmp(token, implicit_w))
                    explicit1 = 0;
                else if (!strcmp(token, explicit_w))
                    explicit1 = 3;
                else if (strcmp(token, tags_w))
                    syntax(token);
            }
            get_known(0, &token[1], ":");
            get_known(0, &token[2], "=");
            token[3] = 0;
        }
        else if (!strcmp(token, exports_w) || !strcmp(token, imports_w))
            while (*token != ';')
                get_must(0, token);
        else if (!*classname && *token >= 'A')
            strcpy(classname, token);
    }
    while (get_token(0, token));
    return -1;
}
예제 #2
0
    void initialize_in_object(O& object, Context* context) const override {
      PluralAssociationBase<O, HasMany<A>>::initialize_in_object(object, context);

      // This is sinful (and undefined behaviour, and probably slow:
      // The aim is to be able to go from pointer to HasMany<A> to pointer to O.
      size_t offset = member_offset(object);
      this->get(object)->get_id_of_owner_ = [=](const HasMany<A>& anchor) -> PrimaryKey {
        const O* obj = reinterpret_cast<const O*>(reinterpret_cast<const char*>(&anchor) - offset);
        auto t = get_type<O>()->primary_key();
        auto p = dynamic_cast<const PropertyOfBase<O, PrimaryKey>*>(t);
        if (p == nullptr) {
          throw AssociationError{"Owner of HasMany association has a primary key that isn't a PrimaryKey property."};
        }
        return p->get_known(*obj);
      };
    }
예제 #3
0
static long get_tag(
    char *token)
{
/**
Procedure:
1. IF no next token, exit with fatal message
   IF token is APPLICATION OR PRIVATE OR UNIVERSAL
        Set tag to application specific
        IF no next token, exit with fatal message
   ELSE set tag to content specific
   IF token is an upper bound, get its value
   IF token is an ID, translate it
   ELSE
        IF token is an ID, copy that into token
        Get number in token
2. Convert number to true tag
   Return tag
**/
    long ttag,
        tmp;
    char *c;
    struct id_table *idp;
    struct ub_table *ubp;

    get_must(0, token);         /* step 1 */
    if (!strcmp(token, application_w) || !strcmp(token, private_w) ||
        !strcmp(token, universal_w))
    {
        if (*token == 'A')
            ttag = ASN_APPL_SPEC;
        else if (*token == 'P')
            ttag = ASN_PRIV_SPEC;
        else
            ttag = 0;
        get_must(0, token);
    }
    else
        ttag = ASN_CONT_SPEC;
    if (token[0] == '0' && (token[1] | 0x20) == 'x')
    {                           /* special stuff for inexpressible tags */
        for (c = &token[2], tmp = 0; *c >= '0' && *c <= 'f'; c++)
        {
            tmp <<= 4;
            if (*c > 'F')
                *c -= 0x20;
            if (*c > '9')
                *c -= 7;
            tmp |= (*c - '0');
        }
    }
    else
    {
        if ((ubp = is_ub(token)))
        {
            sprintf(token, "%ld", ubp->val);
            for (c = token; *c >= '0' && *c <= '9'; c++);
            *c = 0;
        }
        else if ((idp = find_id(token)))
            strcpy(token, idp->val);
        for (c = token, tmp = 0; *c >= '0' && *c <= '9';
             tmp = (tmp * 10) + *c++ - '0');
    }
    if (*c++)
        syntax(token);
    get_known(0, c, "]");
    if (token[1] > '9')
    {                           /* more for inexpressible tags */
        ttag |= tmp >> 8;
        ttag |= (tmp & 0xFF) << 8;
    }
예제 #4
0
int read_item(
    int parent,
    void (*func)(void))
{
/**
Function: General function to read an item and fill in appropriate global
variables
Input: File descriptor for input
Outputs: Sets option flags
         Fills in tag, type, min, max, itemname, subclass, subtype,
            defaultname and numstring
Procedure:
1. WHILE token is neither ',' NOR '}'
        IF token is '[', get tag
        ELSE IF token is '('
            IF enumerated flag set, get material for tag or sub_val
            ELSE Get min-max
        ELSE IF token is CHOICE, set constructed bit in type
        ELSE IF token is COMPONENTS, do components stuff
        ELSE IF token is DEFAULT, make defaultname and set default flag
        ELSE IF token is DEFINED, do the defined thing to fill in defined_by
        ELSE IF token is EMPTY, do nothing
        ELSE IF token is EXPLICIT, set temporary explicit flag
        ELSE IF token is FUNCTION
            Set type
            Get all tokens up to comma or right brace
        ELSE IF token is IMPLICIT, clear temporary explicit flag
        ELSE IF token is OF, error
        ELSE IF token is OPTIONAL, set OPTIONAL flag in options
        ELSE IF token is SIZE, get min-max
        ELSE IF token is TABLE
            Get table name to skip it
            Set table variable
        ELSE IF token is TAGS OR UNIQUE, swallow it
        ELSE IF token is a defined type
            IF this is a table AND (there's a type OR a subclass already)
                append token to alt_subclasses
            ELSE IF have a subclass already, syntax error
            ELSE IF have no type yet, use that
            ELSE IF explicit tagging, set subtype
            ELSE
                'Or' the constructed bit into type
                Get expected sequel to token, if any
        ELSE IF token begins with a number
            IF TABLE bit is set, convert number
            ELSE IF enumerated flag is set
                Put token into itemname prefixed with e
                Set enumerated flag
        ELSE IF in a table AND (token is TRUE OR FALSE)
            Make type boolean
            Put token in subclass
        ELSE IF name begins with a capital letter
            IF this is a table item AND (there is already a subclass OR a type)
                Append this to the alt_subclasses
            ELSE IF there is already a subclass OR a type, syntax error
            ELSE set the subclass and option from the token
        ELSE IF name begins with a lower-case letter
            IF this is a table item, increment the array count
            IF no itemname so far, set token in itemname with options
        IF no next token, return -1
2. IF token is '}'
        Peek at the next token
        IF it's '(', set the constrained flag
   Return 0
**/
    char *c;
    long tmp;
    struct name_table *ntbp;
    struct id_table *idp = (struct id_table *)0;
    int parens;
    struct alt_subclass *altscp = (struct alt_subclass *)0;
    while (*token != ',' && *token != '}')
    {
        if (*token == '[')
        {
            tmp = get_tag(token);
            if (tag >= 0)
                tag |= tmp;
            else
                tag = tmp;
        }
        else if (*token == '(')
        {
            if ((flags & ASN_ENUM_FLAG))
            {
                if (!get_token(0, token))
                    syntax(itemname);
                if (*(c = token) == '_')
                    c++;
                if (find_name(classname)->type == ASN_OBJ_ID)
                {
                    if (*c > '2')
                    {
                        if (!(idp = find_id(c)))
                            syntax(c);
                        strcpy(c, idp->val);
                        idp = (struct id_table *)0;
                    }
                    sub_val = (char *)calloc(1, strlen(c) + 1);
                    strcpy(sub_val, c);
                }
                else if (*c >= '0' && *c <= '9')
                {
                    for (integer_val = 0; *c;
                         integer_val = (integer_val * 10) + *c++ - '0');
                    if (*token == '_')
                        integer_val = -integer_val;
                }
                else
                {
                    integer_val = find_ub(token);
                    add_child(token, parent, 0, (ulong) - 1, 0);
                }
                if (!get_known(0, token, ")"))
                    syntax(itemname);
            }
            else
                get_paren(token, &min, &max, parent);
        }
        else if (!strcmp(token, choice_w))
        {
            if (tag >= 0)
                tag |= ASN_CONSTRUCTED;
            else if (type >= 0)
                type |= ASN_CONSTRUCTED;
            else
                type = ASN_CONSTRUCTED;
        }
        else if (!strcmp(token, components_w))
            do_components(func);
        else if (!strcmp(token, default_w))
        {
            option |= (ASN_OPTIONAL_FLAG | ASN_DEFAULT_FLAG);
            get_token(0, token);
            c = defaultname;
            if (*token >= '0' && *token <= '9')
                *c++ = '0';
            else if (!strcmp(token, empty_w) || !strcmp(token, null_w) ||
                     (*token == '"' && token[1] == '"'))
                cat(token, "{");
            strcpy(c, token);
        }
        else if (!strcmp(token, defined_w))
        {
            do_defined();
        }
        else if (!strcmp(token, empty_w));
        else if (!strcmp(token, explicit_w))
            explicit1 |= 1;
        else if (!strcmp(token, function_w))
        {
            type = ASN_FUNCTION;
            for (c = itemname, parens = 0; get_must(0, token) && (parens ||
                                                                  (*token !=
                                                                   ','
                                                                   && *token !=
                                                                   '}'));)
            {
                if (*token == '(')
                    parens++;
                else if (*token == ')')
                    parens--;
                c = cat(cat(c, token), " ");
            }
            break;
        }
        else if (!strcmp(token, implicit_w))
        {
            explicit1 &= ~1;
            if (*subclass && tag < ASN_APPL_SPEC
                && (ntbp = find_name(subclass)) && ntbp->name)
            {
                if (type < 0)
                    type = ntbp->type;
                else if (ntbp->type != -1)
                    type |= (ntbp->type & ASN_CONSTRUCTED);
            }
        }
        else if (!strcmp(token, in_w))
        {
            if (!*definer)
                syntax(token);
            if (!get_token(0, inclass))
                syntax(definer);
        }
        else if (!strcmp(token, of_w))
            syntax(token);
        else if (!strcmp(token, optional_w))
        {
            option |= ASN_OPTIONAL_FLAG;
            if (altscp)
            {
                altscp->options = option;
                option &= ~(ASN_OPTIONAL_FLAG);
            }
        }
        else if (!strcmp(token, size_w))
        {
            get_size(token, &min, &max, parent);
            // if (type == ASN_UTCTIME || type == ASN_GENTIME) min = max = 0;
        }
        else if (!strcmp(token, table_w))
        {
            if (!get_token(0, tablename))
                syntax(table_w);
            if (*tablename < 'A' || *tablename > 'Z')
                syntax(tablename);
            option |= ASN_TABLE_FLAG;
        }
        else if (!strcmp(token, tags_w) || !strcmp(token, unique_w));
        else if ((tmp = (int)find_type(token)) != ASN_NOTYPE)
        {
            if ((flags & ASN_TABLE_FLAG) && (*subclass || type >= 0))
                altscp = append_subclasses(token);
            else if (*subclass)
                syntax(token);
            if (type < 0)
                type = (ulong) tmp;
            else if ((explicit1 & 1))
                subtype = (short)tmp;
            else if (tmp > 0)
                type |= (tmp & ASN_CONSTRUCTED);
            get_expected(0, tmp, token);
        }
        else if ((*token >= '0' && *token <= '9') ||
                 (*itemname && (idp = find_id(token))) || is_ub(token))
        {
            if (*token > '9')
            {
                if (idp)
                    cat(token, idp->val);
                else
                {
                    add_name(token, -1, 0);     /* keep it off the 'Defined
                                                 * but not used' list */
                    sprintf(token, "%ld", find_ub(token));
                }
            }
            if ((flags & ASN_TABLE_FLAG))
            {
                if (*token >= '0' && *token <= '9')
                    cvt_number(numstring, token);
            }
            else if ((flags & ASN_ENUM_FLAG))
            {
                if (!*itemname)
                    cat(cat(itemname, "e"), token);
                else
                {
                    if (*(c = token) == '_')
                        c++;
                    for (integer_val = 0; *c;
                         integer_val = (integer_val * 10) + *c++ - '0');
                    if (*token == '_')
                        integer_val = -integer_val;
                }
            }
            idp = (struct id_table *)0;
        }
        else if ((flags & ASN_TABLE_FLAG) && (!strcmp(token, false_w) ||
                                              !strcmp(token, true_w)
                                              || !strcmp(token, either_w)))
        {
            type = ASN_BOOLEAN;
            cat(subclass, token);
        }
        else if ((*token >= 'A' && *token <= 'Z') || *token == '*')
        {
            if ((flags & ASN_TABLE_FLAG))
            {
                if (!strcmp(token, "NONE"))
                    cat(token, "AsnNone");
                if (*subclass || type > 0)
                    altscp = append_subclasses(token);
                else
                    option |= set_name_option(subclass, token);
            }
            else if ((type > 0 && type < ASN_CHOICE) || *subclass)
                syntax(token);
            else
                option |= set_name_option(subclass, token);
        }
        else if (*token >= 'a' && *token <= 'z')
        {
            if ((flags & ASN_TABLE_FLAG))
                array++;
            if (*itemname)
                warn(MSG_SYNTAX_ERR, token);
            else
                cat(itemname, token);
        }
        if (!get_token(0, token))
            return -1;
    }
    if (*definer && !*inclass)
        cat(inclass, classname);
    if (*token == '}' && *peek_token(0) == '(')
    {
        get_known(0, &token[2], "(");
        get_def_paren(&token[2]);
    }
    return 0;
}