Exemplo n.º 1
0
bool str_is_slot_name(const char* s, fint len) {
  assert(len >= 0, "shouldn't be negative length");
  if (len == 0) {
    return false;
  }
  char c = *s;
  if (!is_lower(c)) {
    if (!is_punct(c))     return false;
    switch (c) {
     case '^':      case '|':       case '\\':   case '.':
       if (len == 1) return false;
    }
    for (int i = 0;  i < len; ) {
      c = s[i++];
      if (! is_punct(c)) return false;
      switch (c) {
       case '(':  case ')':  case '\'':  case '\"':  case ':':  
       case '[': case ']':
        return false;
      }
    }
    return true;
  }
  for (int i = 1;  i < len;  ) {
    c = s[i++];
    if (is_id_char(c))   continue;
    if (c != ':')        return false;
    if (i == len)        return true;  // this was final ":"
    if (!is_upper(s[i])) return false; // after ":" must be uppercase
    if (s[len-1] != ':') return false; // one ":" -> last is ":"
  }
  return true;
}
Exemplo n.º 2
0
bool CMaExpander::IsValidToken(const CC_STRING& s)
{
	const char *p = s.c_str();
	if(p == NULL)
		return false;
	if( ! isalpha(*p) && *p != '_' )
		return false;
	for(p++; *p != '\0'; p++ ) {
		if( isblank(*p) )
			break;
		if( ! is_id_char(*p) )
			return false;
	}
	return true;
}
Exemplo n.º 3
0
char * get_refid_value( char * p )
{
    char  * pa;
    char  * pe;
    int     len;
    char    c;

    p = get_att_value( p );

    if( val_start == NULL || val_len == 0 ) {   // no valid id
        return( p );
    }
    pa = val_start;
    while( is_id_char( *pa ) ) {
        pa++;
    }

    len = pa - val_start;
    pe = val_start + len;
    if( len > 7 ) {                     // wgml 4 warning level
        c = *pe;
        *pe = '\0';
        g_warn( wng_id_xxx, val_start );
        *pe = c;
        g_info( inf_id_len );
        file_mac_info();
        wng_count++;
    }

    /***************************************************************/
    /*  restrict the length to ID_LEN (15) in the hope that no     */
    /*  truncation occurs                                          */
    /*  wgml4 warns about ids of more than 7 chars, but processes  */
    /*  much longer ids                                  TBD       */
    /***************************************************************/

    val_len = min( ID_LEN, len );       // restrict length
    *(val_start + val_len) = '\0';
    return( p );
}
Exemplo n.º 4
0
bool        process_tag( gtentry * ge, mac_entry * me )
{
    bool            processed;
    gaentry     *   ga;
    gavalentry  *   gaval;
    char        *   p;
    char        *   p2;
    int             rc;
    char            quote;
    char            longwork[20];
    bool            tag_end_found = false;

    processed = true;
    init_dict( &loc_dict );

    add_defaults_to_dict( ge, &loc_dict );

    /***********************************************************************/
    /*  scan input for attributes and / or tagtext                         */
    /***********************************************************************/

    p = tok_start + ge->namelen + 1;    // over tagname

    if( ge->attribs != NULL ) {     // only process attributes if they exist
        while( *p == ' ' ) {        // not yet end of tag, process attributes

            while( *p == ' ' ) {        // over WS to attribute
                p++;
            }
            if( *p == '.' ) {
                tag_end_found = true;
                break;
            }
            p2 = token_buf;
            while( is_id_char( *p ) ) {
                *p2++ = *p++;
            }
            *p2 = '\0';
            if( p2 != token_buf ) {     // ignore nullstring
                for( ga = ge->attribs; ga != NULL; ga = ga->next ) {// all attrs
                    if( !stricmp( ga->name, token_buf ) ) {
                        ga->attflags |= att_proc_seen; // attribute specified
                        if( ga->attflags & att_auto ) {
                            auto_att_err();
                            break;
                        }

                        if( *p == '=' ) {   // value follows
                            ga->attflags |= att_proc_val;

                            p++;        // over =
                            p2 = token_buf;
                            if( is_quote_char( *p ) ) {
                                quote = *p++;
                                while( *p && *p != quote ) {// quoted value
                                    *p2++ = *p++;
                                }
                                if( *p == quote ) {
                                    p++;// over ending quote
                                }
                            } else {
                                quote = '\0';
                                while( *p && (*p != ' ') && (*p != '.') ) {
                                    *p2++ = *p++;
                                }
                            }
                            *p2 = '\0';
                            if( ga->attflags & att_off ) {// attribute inactive
                                continue;
                            }
                            if( ga->attflags & att_upper ) {// uppercase option
                                strupr( token_buf );
                            }

                            scan_err = check_att_value( ga );

                        } else {// special for range set default2 if no value
                            if( ga->attflags & att_range ) {
                                for( gaval = ga->vals; gaval != NULL;
                                     gaval = gaval->next ) {
                                     if( gaval->valflags & val_range ) {
                                        break;
                                     }
                                }
                                if( gaval != NULL ) {
                                     sprintf( token_buf, "%d",
                                              gaval->a.range[3] );
                                     rc = add_symvar( &loc_dict, ga->name,
                                                      token_buf, no_subscript,
                                                      local_var );
                                }
                            }
                        }
                        break;
                    }
                }
                if( ga == NULL ) {      // attribute Not found
                    char        linestr[MAX_L_AS_STR];

                    processed = false;
                    wng_count++;
                    //***WARNING*** SC--040: 'abd' is not a valid attribute name
                    g_warn( wng_att_name, token_buf );
                    if( input_cbs->fmflags & II_macro ) {
                        ultoa( input_cbs->s.m->lineno, linestr, 10 );
                        g_info( inf_mac_line, linestr, input_cbs->s.m->mac->name );
                    } else {
                        ultoa( input_cbs->s.f->lineno, linestr, 10 );
                        g_info( inf_file_line, linestr, input_cbs->s.f->filename );
                    }
                    show_include_stack();
                }
            }
            /***************************************************************/
            /*  check for tag end .                                        */
            /***************************************************************/
            if( *p == ' ' ) {
                continue;               // not yet at buffer / tag end
            }
#if 0
            /***************************************************************/
            /*  continue scanning for attriutes on next line if not tag end*/
            /*  This does not work for constructs such as                  */
            /*                                                             */
            /*  :hdref refid=diffs                                         */
            /*  .bd to determine if you need to recompile your application.*/
            /*  from docs\doc\gs\intro.gml line 37 f                       */
            /***************************************************************/

            if( *p != '.' ) { //
                if( get_line( true ) ) {
                    p = buff2;
                } else {
                    *p = '\0';
                }
            } else {
                tag_end_found = true;
            }
#else
            if( (*p == '.') || (*p == '\0') ) {
                tag_end_found = true;
            }
#endif
        }

        /*******************************************************************/
        /*  check for missing reqrd attributes                             */
        /*******************************************************************/
        *token_buf = '\0';
        for( ga = ge->attribs; ga != NULL; ga = ga->next ) {// for all attrs
            if( ga->attflags & att_req ) {
                if( !(ga->attflags & att_proc_seen) ) {
                    if( *token_buf != '\0' ) {
                        strcat( token_buf, " '" );
                    } else {
                        strcpy( token_buf, "'" );
                    }
                    strcat( token_buf, ga->name );
                    strcat( token_buf, "' " );
                }
            }
        }
        if( *token_buf != '\0' ) {      // some req attr missing
            char        linestr[MAX_L_AS_STR];

        // the errmsg in wgml 4.0 is wrong, it shows the macroname, not tag.
// ****ERROR**** SC--047: For the tag '@willi', the required attribute(s)
//                       'muss2'
//                       'muss'
//                       have not been specified

            processed = false;
            err_count++;
            g_err( err_att_req, ge->name, token_buf );
            if( input_cbs->fmflags & II_macro ) {
                ultoa( input_cbs->s.m->lineno, linestr, 10 );
                g_info( inf_mac_line, linestr, input_cbs->s.m->mac->name );
            } else {
                ultoa( input_cbs->s.f->lineno, linestr, 10 );
                g_info( inf_file_line, linestr, input_cbs->s.f->filename );
            }
            show_include_stack();
        }

        if( *p == '.' ) {               // does text follow tag end
            if( strlen( p + 1 ) > 0 ) {
                if( ge->tagflags & tag_texterr ) { // no text allowed
                    tag_text_err( ge->name );
                    processed = false;
                }
            } else {
                if( ge->tagflags & tag_textreq ) {  // reqrd text missing
                    tag_text_req_err( ge->name );
                    processed = false;
                }
            }
            strcpy( token_buf, p + 1 );
            rc = add_symvar( &loc_dict, "_", token_buf, no_subscript, local_var );
            p += strlen( token_buf );
        }

        scan_start = p + 1;             // all processed
        /*******************************************************************/
        /*  add standard symbols to dict                                   */
        /*******************************************************************/

        rc = add_symvar( &loc_dict, "_tag", ge->name, no_subscript, local_var );
        ge->usecount++;
        sprintf( longwork, "%d", ge->usecount );
        rc = add_symvar( &loc_dict, "_n", longwork, no_subscript, local_var );


        add_macro_cb_entry( me, ge );   // prepare GML macro as input
        input_cbs->local_dict = loc_dict;
        inc_inc_level();                // start new include level
        if( ge->tagflags & tag_cont ) {   // +++++++++++++++++++ TBD trial
            post_space = 0;
            ProcFlags.ct = true;
        }

        if( input_cbs->fmflags & II_research && GlobalFlags.firstpass ) {
            print_sym_dict( input_cbs->local_dict );
        }
    } else {                            // user-defined tag has no attributes
        if( ge->tagflags & tag_texterr ) {  // no text allowed
            // '.' or CW_sep_char immediately after the tag does not count as text
            if( (*p == '.') || (*p == CW_sep_char ) ) {
                p++;
            }
            while( *p == ' ' ) {        // spaces don't count as text
                p++;
            }
            if( *p ) {                  // text found
                tag_text_err( ge->name );
                processed = false;
                return( processed );
            }
        }
        if( ge->tagflags & tag_textreq ) {  // text is required
            // per wgml 4.0 behavior
            if( *p == CW_sep_char ) {
                processed = false;
                return( processed );
            }
            // '.' immediately after the tag does not count as text
            if( *p == '.' ) {
                p++;
            }
            while( *p == ' ' ) {        // spaces don't count as text
                p++;
            }
            if( !*p ) {                 // no text found
                tag_text_req_err( ge->name );
                processed = false;
                return( processed );
            }
        }
        // per wgml 4.0 behavior
        if( *p == CW_sep_char ) {
            processed = false;
            return( processed );
        }
        // '.' immediately after the tag is not passed to the macro
        if( *p == '.' ) {
            p++;
        }
        strcpy( token_buf, p );
        rc = add_symvar( &loc_dict, "_", token_buf, no_subscript, local_var );
        p += strlen( token_buf );

        scan_start = p + 1;             // all processed
        /*******************************************************************/
        /*  add standard symbols to dict                                   */
        /*******************************************************************/

        rc = add_symvar( &loc_dict, "_tag", ge->name, no_subscript, local_var );
        ge->usecount++;
        sprintf( longwork, "%d", ge->usecount );
        rc = add_symvar( &loc_dict, "_n", longwork, no_subscript, local_var );


        add_macro_cb_entry( me, ge );   // prepare GML macro as input
        input_cbs->local_dict = loc_dict;
        inc_inc_level();                // start new include level
        if( ge->tagflags & tag_cont ) { // +++++++++++++++++++ TBD trial
            post_space = 0;
            ProcFlags.ct = true;
        }

        if( input_cbs->fmflags & II_research && GlobalFlags.firstpass ) {
            print_sym_dict( input_cbs->local_dict );
        }
    }

    return( processed );
}
Exemplo n.º 5
0
/* _agstrcanon:
 * Canonicalize ordinary strings. 
 * Assumes buf is large enough to hold output.
 */
static char *_agstrcanon(char *arg, char *buf)
{
    char *s, *p;
    unsigned char uc;
    int cnt = 0, dotcnt = 0;
    int needs_quotes = FALSE;
    int maybe_num;
    int backslash_pending = FALSE;
    static const char *tokenlist[]	/* must agree with scan.l */
	= { "node", "edge", "strict", "graph", "digraph", "subgraph",
	NIL(char *)
    };
    const char **tok;

    if (EMPTY(arg))
	return "\"\"";
    s = arg;
    p = buf;
    *p++ = '\"';
    uc = *(unsigned char *) s++;
    maybe_num = isdigit(uc) || (uc == '.') || (uc == '-');
    while (uc) {
	if (uc == '\"') {
	    *p++ = '\\';
	    needs_quotes = TRUE;
	} 
	else if (maybe_num) {
	    if (uc == '-') {
		if (cnt) {
		    maybe_num = FALSE;
		    needs_quotes = TRUE;
		}
	    }
	    else if (uc == '.') {
		if (dotcnt++) {
		    maybe_num = FALSE;
		    needs_quotes = TRUE;
		}
	    }
	    else if (!isdigit(uc)) {
		maybe_num = FALSE;
		needs_quotes = TRUE;
	    }
	}
	else if (!ISALNUM(uc))
	    needs_quotes = TRUE;
	*p++ = (char) uc;
	uc = *(unsigned char *) s++;
	cnt++;
	
	/* If breaking long strings into multiple lines, only allow breaks after a non-id char, not a backslash, where the next char is an
 	 * id char.
	 */
	if (Max_outputline) {
            if (uc && backslash_pending && !(is_id_char(p[-1]) || (p[-1] == '\\')) && is_id_char(uc)) {
        	*p++ = '\\';
        	*p++ = '\n';
        	needs_quotes = TRUE;
        	backslash_pending = FALSE;
		cnt = 0;
            } else if (uc && (cnt >= Max_outputline)) {
        	if (!(is_id_char(p[-1]) || (p[-1] == '\\')) && is_id_char(uc)) {
	            *p++ = '\\';
    	            *p++ = '\n';
	            needs_quotes = TRUE;
		    cnt = 0;
        	} else {
                    backslash_pending = TRUE;
        	}
	    }
	}
    }
    *p++ = '\"';
    *p = '\0';
    if (needs_quotes || ((cnt == 1) && ((*arg == '.') || (*arg == '-'))))
	return buf;

    /* Use quotes to protect tokens (example, a node named "node") */
    /* It would be great if it were easier to use flex here. */
    for (tok = tokenlist; *tok; tok++)
	if (!strcasecmp(*tok, arg))
	    return buf;
    return arg;
}
Exemplo n.º 6
0
Token* Scanner::read_name(fint c) {
  Token::TokenType t;
  fint l = line;
  fint col = column - 1;
  const char* ss = sourceAddr() - 1;
  fint len;
  if (c == ':') {
    t = Token::ARG;
    len = 0;
  } else {
    t = c == '_' ? Token::PRIMNAME : Token::NAME;
    len = 1;
    buffer[0] = char(c);
  }
  while (c = get_char(), is_id_char(c)) {
    buffer[len++] = char(c);
  }
  if (c == ':' && (t == Token::NAME || t == Token::PRIMNAME)) {
    buffer[len++] = char(c);
    if (is_upper((fint)*buffer)) t = Token::CAPKEYWORD;
    else
      t = c == '_' ? Token::PRIMKEYWORD : Token::KEYWORD;
  } 
  else {
    push_char(c);
  }
  buffer[len] = '\0';
  if (t == Token::ARG && len == 0) {
    t = as_TokenType(':');
  } else if (t == Token::NAME || t == Token::PRIMNAME) {
    c = get_char();
    if (c == '.') {
      c = get_char();
      push_char(c);
      if (is_id_alpha(c) || is_punct(c)) {
        t = Token::DELEGATE;
      } else {
        push_char('.');
      }
    } else {
      push_char(c);
    }
  }
  if (strcmp(buffer, "self") == 0) {
    if (t == Token::NAME) {
      t = Token::SELF_TOKEN;
    } else {
      return TokenizingError(
                             "using \"self\" as a parent name for a directed resend");
    }
  } else if (strcmp(buffer, "resend") == 0) {
    if (t == Token::DELEGATE) {
      t = Token::RESEND_TOKEN;
    } else {
      return TokenizingError("not using \"resend\" in a resend");
    }
  }
  String* s;
  if (t == Token::NAME    || t == Token::PRIMNAME    || t == Token::ARG || t == Token::DELEGATE ||
      t == Token::KEYWORD || t == Token::PRIMKEYWORD || t == Token::CAPKEYWORD) {
    s = new String(copy_string(buffer));
  } else {
    s = NULL;
  }
  return new Token(t, s, l, col, ss);
}
Exemplo n.º 7
0
static void split_at_GML_tag( void )
{
    char    *   p;
    char    *   p2;
    char    *   pchar;
    char        c;
    bool        layoutsw;
    size_t      toklen;

    if( *buff2 == GML_char ) {
        if( !strnicmp( (buff2 + 1), "CMT", 3 ) &&
            ((*(buff2 + 4) == '.') || (*(buff2 + 4) == ' ')) ) {
            return;                     // no split for :cmt. line
        }
    }

    /***********************************************************************/
    /*  Look for GML tag start char(s) until a known tag is found          */
    /*  then split the line                                                */
    /***********************************************************************/
    pchar = strchr( buff2 + 1, GML_char );
    while( pchar != NULL ) {
        while( *(pchar + 1) == GML_char ) {
            pchar++;                    // handle repeated GML_chars
        }
        for( p2 = pchar + 1;
             is_id_char( *p2 ) && (p2 < (buff2 + buf_size));
             p2++ ) /* empty loop */ ;

        if( (p2 > pchar + 1)
            && ((*p2 == '.') ||
                is_space_tab_char( *p2 ) ||
                (*p2 == '\0') ||
                (*p2 == GML_char) ) ) { // 'good' tag end

            c = *p2;
            if( ProcFlags.layout && (c == '\t') ) {
                c = ' ';                // replace tab with space in layout
            }
            *p2 = '\0';                 // null terminate string
            toklen = p2 - pchar - 1;

            /***************************************************************/
            /* Verify valid user or system tag                             */
            /***************************************************************/
            if( (find_tag( &tag_dict, pchar + 1 ) != NULL) ||
                (find_sys_tag( pchar + 1, toklen ) != NULL) ||
                (find_lay_tag( pchar + 1, toklen ) != NULL) ) {

                *p2 = c;

                if( input_cbs->fmflags & II_sol ) {
                // remove spaces before tags at sol in restricted sections
                // in or just before LAYOUT tag
                    layoutsw = ProcFlags.layout;
                    if( !layoutsw && (strncmp( "LAYOUT", pchar + 1, 6 ) == 0 ) ) {
                        layoutsw = true;
                    }
                    if( (rs_loc > 0) || layoutsw ) {
                        p = buff2;
                        while( is_space_tab_char( *p ) ) {
                            p++;
                        }
                        if( p == pchar ) {  // only leading blanks
                            memmove( buff2, pchar, buf_size - (p - buff2) );
                            buff2_lg = strlen( buff2 );// new length
                            pchar = strchr( buff2 + 1, GML_char );  // try next GMLchar
                            continue;       // dummy split done try again
                        }
                    }
                }
                split_input( buff2, pchar, false );// split line
                if( ProcFlags.literal ) {   // if literal active
                    if( li_cnt < LONG_MAX ) {// we decrement, adjust for split line
                        li_cnt++;
                    }
                }
                break;                  // we did a split stop now
            } else {
                *p2 = c;
            }
        }
        pchar = strchr( pchar + 1, GML_char );  // try next GMLchar
    }
}
Exemplo n.º 8
0
static void scan_gml( void )
{
    inputcb     *   cb;
    char        *   p;
    int             toklen;
    int             k;
    char            csave;
    bool            processed;
    gtentry     *   ge;                 // GML user tag entry
    mac_entry   *   me;                // script macro for processing GML tag
    char            linestr[MAX_L_AS_STR];
    char            tok_upper[TAG_NAME_LENGTH];

    cb = input_cbs;

    p = scan_start + 1;
    tok_start = scan_start;
    while( is_id_char( *p ) && p <= scan_stop ) { // search end of TAG
        p++;
    }
    scan_start = p;                      // store argument start address
    toklen = p - tok_start - 1;
    csave = *p;
    *p = '\0';
    if( toklen >= TAG_NAME_LENGTH ) {
        err_count++;
        // SC--009 The tagname is too long
        if( cb->fmflags & II_macro ) {
            ultoa( cb->s.m->lineno, linestr, 10 );
            g_err( err_tag_name, tok_start + 1, linestr, "macro",
                   cb->s.m->mac->name );
        } else {
            ultoa( cb->s.f->lineno, linestr, 10 );
            g_err( err_tag_name, tok_start + 1, linestr, "file",
                   cb->s.f->filename );
        }
        if( inc_level > 0 ) {
            show_include_stack();
        }
        *p = csave;
        scan_start = tok_start;         // process as text
        return;
    }

    if( GlobalFlags.firstpass && cb->fmflags & II_research ) {

        if(  stricmp( tok_start + 1, "cmt" ) ) {   // quiet for :cmt.

            if( cb->fmflags & II_macro ) {
                printf_research( "L%d    %c%s tag found in macro %s(%d)\n\n",
                                 inc_level, GML_char, tok_start + 1,
                                 cb->s.m->mac->name, cb->s.m->lineno );
            } else {
                printf_research( "L%d    %c%s tag found in file %s(%d)\n\n",
                                 inc_level, GML_char, tok_start + 1,
                                 cb->s.f->filename, cb->s.f->lineno );
            }
        }
        add_GML_tag_research( tok_start + 1 );
    }

    if( ProcFlags.layout ) {
        ge = NULL;                      // no user tags within :LAYOUT
    } else {
        ge = find_tag( &tag_dict, tok_start + 1 );
    }
    processed = false;
    me = NULL;
    if( ge != NULL ) {                  // GML user defined Tag found
        *p = csave;
        if( ge->tagflags & tag_off ) {  // inactive, treat as text
            scan_start = tok_start;
            return;
        }
        me = find_macro( macro_dict, ge->macname );
        if( me == NULL ) {
            err_count++;
            // SC--037: The macro 'xxxxxx' for the gml tag 'yyyyy'
            //          is not defined
            if( cb->fmflags & II_macro ) {
                ultoa( cb->s.m->lineno, linestr, 10 );
                g_err( err_tag_macro, ge->macname, ge->name,
                         linestr, "macro", cb->s.m->mac->name );
            } else {
                ultoa( cb->s.f->lineno, linestr, 10 );
                g_err( err_tag_macro, ge->macname, ge->name,
                         linestr, "file", cb->s.f->filename );
            }
            if( inc_level > 0 ) {
                show_include_stack();
            }
            *p = csave;
            scan_start = tok_start;         // process as text
            return;
        } else {

        /*******************************************************************/
        /*  The following is to prevent an endless loop                    */
        /*  Example from ow documentation:                                 */
        /*  .gt ZH1 add zh1                                                */
        /*  .gt H1 add zh1                                                 */
        /*  .dm zh1 begin                                                  */
        /*  ...                                                            */
        /*  :H1      <---- overridden gml tag                              */
        /*  ...                                                            */
        /*  .dm zh1 end                                                    */
        /*                                                                 */
        /*  we call the predefined :H1  instead                            */
        /*******************************************************************/

            if( (cb->fmflags & II_tag) && (cb->s.m->mac == me) ) {
                me = NULL;
            }
        }
    }
    if( me != NULL ) {                  // usertag and coresponding macro ok
        processed = process_tag( ge, me );
    } else {
        *p ='\0';
        for( k = 0; k <= toklen; k++ ) {
            tok_upper[k] = toupper( *(tok_start + 1 + k) );
        }
        tok_upper[k] = '\0';

        if( ProcFlags.layout ) {        // different tags within :LAYOUT
            for( k = 0; k < LAY_TAGMAX; ++k ) {
                if( toklen == lay_tags[k].taglen ) {
                    if( !strcmp( lay_tags[k].tagname, tok_upper ) ) {
                        *p = csave;
                        lay_ind = -1;   // process tag not attribute

                        lay_tags[k].gmlproc( &lay_tags[k] );

                        processed = true;
                        lay_ind = k;    // now process attributes if any
                        if( *scan_start == '.' ) {
                            scan_start++;
                        }
                        break;
                    }
                }
            }
            if( !processed ) {          // check for gml only tag in :LAYOUT
                for( k = 0; k < GML_TAGMAX; ++k ) {
                    if( toklen == gml_tags[k].taglen ) {
                        if( !strcmp( gml_tags[k].tagname, tok_upper ) ) {
                            g_err( err_gml_in_lay, gml_tags[k].tagname );
                            err_count++;
                            file_mac_info();
                            processed = true;
                            scan_start = scan_stop + 1;
                            break;
                        }
                    }
                }
            }
        } else {                        // not within :LAYOUT
            for( k = 0; k < GML_TAGMAX; ++k ) {
                if( toklen == gml_tags[k].taglen ) {
                    if( !strcmp( gml_tags[k].tagname, tok_upper ) ) {
                        if( GlobalFlags.firstpass &&
                            !strcmp(tok_upper, "LAYOUT" ) &&
                            ProcFlags.fb_document_done  ) {

                            g_err( err_lay_too_late );
                            err_count++;
                            file_mac_info();
                            processed = true;
                            scan_start = scan_stop + 1;
                            break;
                        }
                        *p = csave;

                        if( (rs_loc == 0) && !ProcFlags.need_li_lp ) {
                            // no restrictions: do them all
                            gml_tags[k].gmlproc( &gml_tags[k] );
                        } else if( ProcFlags.need_li_lp &&
                                ((gml_tags[k].taglocs & li_lp_tag) != 0) ) {
                            // tag is LP or LI
                            gml_tags[k].gmlproc( &gml_tags[k] );
                        } else if( (gml_tags[k].taglocs & rs_loc) != 0 ) {
                            // tag allowed in this restricted location
                            gml_tags[k].gmlproc( &gml_tags[k] );
                        } else if( (gml_tags[k].tagflags & tag_is_general) != 0 ) {
                            // tag allowed everywhere
                            gml_tags[k].gmlproc( &gml_tags[k] );
                        } else {
                            start_doc_sect();   // if not already done
                            if( ProcFlags.need_li_lp ) {
                                xx_nest_err( err_no_li_lp );
                            } else {            // rs_loc > 0
                                g_err_tag_rsloc( rs_loc, tok_start );
                            }
                        }
                        processed = true;
                        if( *scan_start == '.' ) {
                            scan_start++;
                        }
                        break;
                    }
                }
            }
            if( !processed ) {         // check for layout tag in normal text
                for( k = 0; k < LAY_TAGMAX; ++k ) {
                    if( toklen == lay_tags[k].taglen ) {
                        if( !strcmp( lay_tags[k].tagname, tok_upper ) ) {
                            g_err( err_lay_in_gml, lay_tags[k].tagname );
                            err_count++;
                            file_mac_info();
                            processed = true;
                            scan_start = scan_stop + 1;
                            break;
                        }
                    }
                }
            }
        }
    }
    if( *p == '\0' ) {
        *p = csave;
    }
    if( !processed ) {                  // treat as text
        scan_start = tok_start;
    }
}
Exemplo n.º 9
0
void    gml_hdref( const gmltag * entry )
{
    char    *   p;
    char    *   pa;
    char    *   pe;
    char    *   idp;
    char        quote;
    char        c;
    bool        idseen;
    bool        pageseen;
    bool        withpage;
    size_t      len;
    char        buf64[64];
    ref_entry   *   re;
    static char undefid[] = "\"Undefined Heading\" on page XXX";


    idseen = false;
    pageseen = false;
    withpage = false;
    p = scan_start;
    re = NULL;

    /***********************************************************************/
    /*  Scan attributes  for :HDREF                                        */
    /*  id=                                                                */
    /*  page=                                                              */
    /***********************************************************************/

    for( ;; ) {
        while( *p == ' ' ) {
            p++;
        }
        if( *p == '\0' || *p == '.'  ) {
            break;                      // tag end found
        }

        if( !strnicmp( "page=", p, 5 ) ) {
            p += 5;
            while( *p == ' ' ) {
                p++;
            }
            pa = p;
            if( !strnicmp( "yes", p, 3 ) ) {
                pageseen = true;
                withpage = true;
                p += 3;
            } else {
                if( !strnicmp( "no", p, 2 ) ) {
                    pageseen = true;
                    withpage = false;
                    p += 2;
                } else {
                   g_err( err_inv_att_val );
                   file_mac_info();
                   err_count++;
                   while( *p && (*p != '.') && (*p != ' ') ) p++;
                }
            }
            scan_start = p;
            continue;
        }

        if( !strnicmp( "refid=", p, 6 ) ) {
            p += 6;
            while( *p == ' ' ) {
                p++;
            }
            if( is_quote_char( *p ) ) {
                quote = *p;
                p++;
            } else {
                quote = '\0';
            }
            pa = p;
            while( *p && is_id_char( *p ) ) {
                p++;
            }
            len = __min( ID_LEN, p - pa );// restrict length as in ghx.c

            if( len > 0 ) {
                idseen = true;          // valid id attribute found
                pe = pa + len;
                c = *pe;
                *pe = '\0';
                re = find_refid( ref_dict, strlwr( pa ) );
                if( re != NULL ) {      // id found in ref dict
                    idp = mem_alloc( 4 + strlen( re->text_cap ) );
                    *idp = '"';         // decorate with quotes
                    strcpy( idp + 1, re->text_cap );
                    strcat( idp, "\"" );
                } else {
                    if( GlobalFlags.lastpass ) {
                        g_warn( wng_id_xxx, pa );
                        g_info( inf_id_unknown );
                        file_mac_info();
                        wng_count++;
                    }
                }
                *pe = c;
            }
            if( *p && (quote == *p) ) {
                p++;
            }

            scan_start = p;
            continue;
        }

        /*******************************************************************/
        /* no more valid attributes                                        */
        /*******************************************************************/
        break;
    }
    if( *p == '.' ) {                   // tag end ?
        p++;
    }
    if( idseen ) {                      // id attribute was specified
        bool concatsave = ProcFlags.concat;

        ProcFlags.concat = true;        // make process_text add to line
        if( re == NULL ) {              // undefined refid
            process_text( undefid, g_curr_font_num );
        } else {
            process_text( idp, g_curr_font_num );
            if( withpage || (!pageseen && (page != re->pageno)) ) {
                sprintf_s( buf64, sizeof( buf64 ), "on page %d", re->pageno );
                process_text( buf64, g_curr_font_num );
            }
            mem_free( idp );
        }
        ProcFlags.concat = concatsave;
    } else {
        g_err( err_att_missing );       // id attribute missing
        file_mac_info();
        err_count++;
    }

    scan_start = p;
    return;
}