Пример #1
0
TToken* get_token()
{	
    if(token_buffer != NULL)
    {
        token = token_buffer;
        token_buffer = NULL;
        return token;
    }
        
	TString buffer; 
	States state = S_START;
	char a[2]; // array for hex number
	int c, i=0;

	initString(&buffer, STR_DEFAULT_SIZE); 
	token->data = buffer.data;
	while(1)
	{
		c = fgetc(fp);
		switch(state)
		{
		case S_START:
			switch (c)
			{
				case EOF:
					token->type = TOKEN_EOF;
					return token;
				case '+':
					token->type = TOKEN_ADD;
					return token;
				case '-':
					token->type = TOKEN_SUB;
					return token;
				case '*':
					token->type = TOKEN_MUL;
					return token;
				case '/':
					state = S_DIV;
				    break;
				case '=':
					state = S_ASSIGN;
				    break;
				case '!':
					state = S_EXCM;
				    break;
				case '<':
					state = S_LESS;
				    break;
				case '>':
					state = S_GREAT;
				    break;		
				case '(':
					token->type = TOKEN_LROUND_BRACKET;
					return token;
				case ')':
					token->type = TOKEN_RROUND_BRACKET;
					return token;
				case '{':
					token->type = TOKEN_LCURLY_BRACKET;
					return token;
				case '}':
					token->type = TOKEN_RCURLY_BRACKET;
					return token;	
				case ',':
					token->type = TOKEN_COMMA;
					return token;
				case ';':
					token->type = TOKEN_SEMICOLON;
				    return token;
                case '"':
					state = S_QUOT;
				    break;
				default:
					if(isdigit(c))
					{
						state = S_INT;
						insertIntoString(&buffer, c);	
					}
					else if (isalpha(c) || c == '_')
					{
						state = S_IDENT;
						insertIntoString(&buffer, c);
					}
					else if (isspace(c))
						break;	
					else
						state = S_ERROR;								
			}
		    break;

//********************************************** 
		case S_INT: // INTEGER
			if (isdigit(c))
			{
				insertIntoString(&buffer, c);
			}
			else if(c == '.')
			{
				insertIntoString(&buffer, c);
				state = S_DOT;				
			}
			else if(c == 'E' || c == 'e')
			{
				insertIntoString(&buffer, c);
				state = S_EXPO_E;				
			}
			else
			{
				insertIntoString(&buffer, 0);
				ungetc(c,fp);
				token->type = TOKEN_INT_VALUE;
	            token->data = buffer.data;
				return token;
			}
		    break;

//*************************************************
		case S_DOT: // number DOT
			if (isdigit(c))
			{
				insertIntoString(&buffer, c);
				state = S_DBL;
			}	
			else
			{
				state = S_ERROR;
			}
		    break;

//*************************************************
		case S_DBL: // DOUBLE
			if (isdigit(c))
			{
				insertIntoString(&buffer, c);
			}
			else if(c == 'E' || c == 'e')
			{
				insertIntoString(&buffer, c);
				state = S_EXPO_E;				
			}
			else
			{
				insertIntoString(&buffer, 0);
				ungetc(c,fp);
				token->type = TOKEN_DOUBLE_VALUE;
	            token->data = buffer.data;
				return token;
			}
		    break;

//******************************************************
		case S_EXPO_E: // state S_EXPO_E
			if (isdigit(c))
			{
				insertIntoString(&buffer, c);
				state = S_EXPO;
			}
			else if (c == '+' || c == '-')
			{
				insertIntoString(&buffer, c);
				state= S_EXPO_M;				
			}		
			else
			{
				state = S_ERROR;
			}
		    break;			

//*****************************************************
		case S_EXPO_M: // state S_EXPO_M
			if (isdigit(c))
			{
				insertIntoString(&buffer, c);
				state= S_EXPO;
			}		
			else
			{
				state=S_ERROR;
			}
		    break;	

//*****************************************************
		case S_EXPO: // state S_EXPO
			if (isdigit(c))
				insertIntoString(&buffer, c);
			else
			{
				insertIntoString(&buffer, 0);
				ungetc(c,fp);
				token->type = TOKEN_DOUBLE_VALUE;
	            token->data = buffer.data;
				return token;
			}
		    break;
		
//***************************************************
		case S_IDENT: //STATE IDENTIFIER
			if (isalnum(c) || c == '_')
			{
				insertIntoString(&buffer, c);
			}
			else
			{
				insertIntoString(&buffer, 0);
				token->type = TOKEN_IDENTIFIER;
	            token->data = buffer.data;
				keyword_check();
				ungetc(c,fp);
				return token;
			}
		    break;
//*************************************************************
		case S_DIV: // DIVIDE
			if (c == '/')
				state = S_LCOM;
			else if (c == '*')
				state = S_LBC;			
			else
			{
				ungetc(c,fp);
				token->type = TOKEN_DIV;
				return token;
			}
		    break;	

//***************************************************
		case S_LCOM: // LINE COMMENT
			if (c == '\n')
				state = S_START;
		    break;
				
//****************************************************
		case S_LBC: // LEFT BLOCK COMMENT
			if (c == '*')
				state = S_RBC;
			if(c == EOF)
				state = S_ERROR;
		    break;

//****************************************************
		case S_RBC: //RIGHT BLOCK COMMENT
			if (c == '/')
				state = S_START;
			else if (c == EOF)
				state = S_ERROR;
			else if (c == '*');
			else
				state = S_LBC;
		break;
				
//****************************************************
		case S_ASSIGN: // ASSIGNMENT
			if (c == '=')
			{
				token->type = TOKEN_EQUAL;
				return token;
			}			
			else
			{
				ungetc(c,fp);
				token->type = TOKEN_ASSIGN;
				return token;
			}
	      	 break;	
	
//****************************************************
		case S_EXCM: // EXCLAMATION MARK
			if (c == '=')
			{
				token->type = TOKEN_NOT_EQUAL;
				return token;
			}			
			else
				state = S_ERROR;
		   break;	

//****************************************************
		case S_LESS: // LESS THAN
			if (c=='=')
			{
				token->type=TOKEN_LESS_EQUAL;
				return token;
			}
			else if (c == '<')
			{
				token->type=TOKEN_COUT_BRACKET;
				return token;
			}				
			else
			{
				ungetc(c,fp);
				token->type = TOKEN_LESS;
				return token;
			}
		   break;

//****************************************************
		case S_GREAT: //GREATER THAN
			if (c=='=')
			{
				token->type = TOKEN_GREATER_EQUAL;
				return token;
			}
			else if (c == '>')
			{
				token->type = TOKEN_CIN_BRACKET;
				return token;
			}				
			else
			{
				ungetc(c,fp);
				token->type = TOKEN_GREATER;
				return token;
			}
		   break;

//****************************************************
		case S_QUOT: //QUOTATION
			if (c == '"') 
			{ 
				insertIntoString(&buffer, 0); 
				token->type = TOKEN_STRING_VALUE;
	            token->data = buffer.data;
				return token;
			}
			else if(c == EOF)
			{
				state = S_ERROR;
			}
			else if(c == '\\')
			{
				state = S_ESCAPE;
			}
			else if(c > 31)
			{
				insertIntoString(&buffer, c);
			}
            else
                state = S_ERROR;
		   break;

//****************************************************
		case S_ESCAPE: //ESCAPE SEQUENCES
			if (c == 't')
			{
				insertIntoString(&buffer, '\t');
				state = S_QUOT;
			}
			else if (c == '"')
			{
				insertIntoString(&buffer, '"');
				state = S_QUOT;
			}
			else if (c == '\\')
			{
				insertIntoString(&buffer, '\\');
				state = S_QUOT;
			}
			else if (c == 'n')
			{
				insertIntoString(&buffer, '\n');
				state = S_QUOT;
			}
			else if (c == 'x')
			{
				state = S_HEX_NUMBER;
			}
			else
			{
				state=S_ERROR;	
			}
			break;

//****************************************************	
		case S_HEX_NUMBER: // HEXADECIMAL NUMBER
			if (isxdigit(c) && (i < 2)) // if is hexadigit and i<2
			{
				a[i]=c;
				i++;			
             
                if (i == 2)
                {
                	if ((a[0] == '0') && (a[1] == '0'))
						state=S_ERROR;
					else
					{
                    char hta = hex_to_ascii(a[0], a[1]);
                    insertIntoString(&buffer, hta);
                    state = S_QUOT;
                    i = 0;
                	}
                }
            }
			else
			{
				state=S_ERROR;
			}
			break;

//****************************************************
		case S_ERROR: // ERROR
			exit_error(E_LEX);
		}
	}
}
Пример #2
0
/*----------------------------------------------------------------------
   Function to control flag set/clearing

   Basically, turn the flags into a fake list of features...

   Returns 0 unless user has added a keyword, then 1.

 ----*/
int
flag_maintenance_screen(struct pine *ps, struct flag_screen *flags)
{
    int		  i, lv, lc, maxwidth, offset, need, rv = 0;
    char	  tmp[1200], **p, *spacer;
    CONF_S	 *ctmpa, *first_line;
    struct	  flag_table  *fp;
    OPT_SCREEN_S  screen;

try_again:
    maxwidth = MAX(MIN((ps->ttyo ? ps->ttyo->screen_cols : 80), 150), 30);
    first_line = NULL;
    ctmpa = NULL;

    for(p = flags->explanation; p && *p; p++) {
        new_confline(&ctmpa);
        ctmpa->keymenu   = &flag_keymenu;
        ctmpa->help      = NO_HELP;
        ctmpa->tool      = flag_checkbox_tool;
        ctmpa->flags    |= CF_NOSELECT;
        ctmpa->valoffset = 0;
        ctmpa->value     = cpystr(_(*p));
    }

    /* Now wire flags checkboxes together */
    for(lv = 0, lc = 0, fp = (flags->flag_table ? *flags->flag_table : NULL);
            fp && fp->name; fp++) {	/* longest name */
        if(fp->flag != F_COMMENT) {
            if(lv < (i = utf8_width(_(fp->name))))
                lv = i;
            if(fp->comment && lc < (i = utf8_width(fp->comment)))
                lc = i;
        }
    }

    lv = MIN(lv,100);
    lc = MIN(lc,100);
    if(lc > 0)
        spacer = "    ";
    else
        spacer = "";

    offset = 6;
    if((need = offset + 5 + lv + strlen(spacer) + lc) > maxwidth) {
        offset -= (need - maxwidth);
        offset = MAX(0,offset);
        if((need = offset + 5 + lv + strlen(spacer) + lc) > maxwidth) {
            spacer = " ";
            if((need = offset + 5 + lv + strlen(spacer) + lc) > maxwidth) {
                lc -= (need - maxwidth);
                lc = MAX(0,lc);
                if(lc == 0)
                    spacer = "";
            }
        }
    }

    new_confline(&ctmpa);
    ctmpa->keymenu   = &flag_keymenu;
    ctmpa->help      = NO_HELP;
    ctmpa->tool      = flag_checkbox_tool;
    ctmpa->flags    |= CF_NOSELECT;
    ctmpa->valoffset = 0;
    ctmpa->value     = cpystr("");

    new_confline(&ctmpa);
    ctmpa->keymenu   = &flag_keymenu;
    ctmpa->help      = NO_HELP;
    ctmpa->tool      = flag_checkbox_tool;
    ctmpa->flags    |= CF_NOSELECT;
    ctmpa->valoffset = 0;
    utf8_snprintf(tmp, sizeof(tmp), "%*.*w  %s", offset+3, offset+3, _("Set"), _("Flag/Keyword Name"));
    tmp[sizeof(tmp)-1] = '\0';
    ctmpa->value = cpystr(tmp);

    new_confline(&ctmpa);
    ctmpa->keymenu   = &flag_keymenu;
    ctmpa->help      = NO_HELP;
    ctmpa->tool      = flag_checkbox_tool;
    ctmpa->flags    |= CF_NOSELECT;
    ctmpa->valoffset = 0;
    snprintf(tmp, sizeof(tmp), "%*.*s---  %.*s",
             offset, offset, "",
             lv+lc+strlen(spacer), repeat_char(lv+lc+strlen(spacer), '-'));
    tmp[sizeof(tmp)-1] = '\0';
    ctmpa->value = cpystr(tmp);

    for(fp = (flags->flag_table ? *flags->flag_table : NULL);
            fp && fp->name; fp++) {	/* build the list */
        new_confline(&ctmpa);
        if(!first_line && (fp->flag != F_COMMENT))
            first_line = ctmpa;

        ctmpa->keymenu   = &flag_keymenu;
        ctmpa->tool      = flag_checkbox_tool;
        ctmpa->valoffset = offset;

        if(fp->flag == F_COMMENT) {
            ctmpa->help   = NO_HELP;
            ctmpa->flags |= CF_NOSELECT;
            ctmpa->value  = cpystr(fp->name);
        }
        else {
            ctmpa->help		  = fp->help;
            ctmpa->d.f.ftbl	  = flags->flag_table;
            ctmpa->d.f.fp	  = fp;

            utf8_snprintf(tmp, sizeof(tmp), "[%c]  %-*.*w%s%-*.*w",
                          (fp->set == 0) ? ' ' : (fp->set == 1) ? 'X' : '?',
                          lv, lv, _(fp->name),
                          spacer, lc, lc, fp->comment ? fp->comment : "");
            ctmpa->value = cpystr(tmp);
        }
    }

    memset(&screen, 0, sizeof(screen));
    /*
     * TRANSLATORS: FLAG MAINTENANCE is a screen title.
     * Print something1 using something2.  configuration is something1
     */
    if(conf_scroll_screen(ps, &screen, first_line,
                          _("FLAG MAINTENANCE"),
                          _("configuration"), 0) == FLAG_ADD_RETURN) {
        int flags, r;
        char keyword[500];
        char nickname[500];
        char prompt[500];
        char *error = NULL;
        KEYWORD_S *kw;
        HelpType help;

        /*
         * User is asking to add a new keyword. We will add it to the
         * mailbox if necessary and add it to the keywords list from
         * Setup/Config. Then we will modify the flag_table and present
         * the flag modification screen again.
         */

        ps->mangled_screen = 1;
        keyword[0] = '\0';
        flags = OE_APPEND_CURRENT;
        help = NO_HELP;

        do {
            if(error) {
                q_status_message(SM_ORDER, 3, 4, error);
                fs_give((void **) &error);
            }

            strncpy(prompt, _("Keyword to be added : "), sizeof(prompt)-1);
            prompt[sizeof(prompt)-1] = '\0';
            r = optionally_enter(keyword, -FOOTER_ROWS(ps_global), 0,
                                 sizeof(keyword), prompt, NULL, help, &flags);

            if(r == 3)
                help = help == NO_HELP ? h_type_keyword : NO_HELP;
            else if(r == 1) {
                cmd_cancelled("Add Keyword");
                goto try_again;
            }

            removing_leading_and_trailing_white_space(keyword);

        } while(r == 3 || keyword_check(keyword, &error));

        for(kw = ps->keywords; kw; kw = kw->next) {
            if(kw->kw && !strucmp(kw->kw, keyword)) {
                q_status_message(SM_ORDER, 3, 4, _("Keyword already configured, changing nickname"));
                break;
            }
        }

        snprintf(prompt, sizeof(prompt), _("Optional nickname for \"%s\" : "), keyword);

        nickname[0] = '\0';
        help = NO_HELP;

        do {
            r = optionally_enter(nickname, -FOOTER_ROWS(ps_global), 0,
                                 sizeof(nickname), prompt, NULL, help, &flags);

            if(r == 3)
                help = help == NO_HELP ? h_type_keyword_nickname : NO_HELP;
            else if(r == 1) {
                cmd_cancelled("Add Keyword");
                goto try_again;
            }

            removing_leading_and_trailing_white_space(nickname);

        } while(r == 3);

        if(keyword[0]) {
            char ***alval;
            int offset = -1;
            struct variable *var;

            var = &ps_global->vars[V_KEYWORDS];
            alval = ALVAL(var, Main);

            for(kw = ps->keywords; kw; kw = kw->next) {
                offset++;
                if(kw->kw && !strucmp(kw->kw, keyword)) {
                    /* looks like it should already exist at offset */
                    break;
                }
            }

            if(!kw)
                offset = -1;

            if(offset >= 0 && (*alval) && (*alval)[offset]) {
                fs_give((void **) &(*alval)[offset]);
                (*alval)[offset] = put_pair(nickname, keyword);
            }
            else if(!*alval) {
                offset = 0;
                *alval = (char **) fs_get(2*sizeof(char *));
                (*alval)[offset] = put_pair(nickname, keyword);
                (*alval)[offset+1] = NULL;
            }
            else {
                for(offset=0; (*alval)[offset]; offset++);
                ;

                fs_resize((void **) alval, (offset + 2) * sizeof(char *));
                (*alval)[offset] = put_pair(nickname, keyword);
                (*alval)[offset+1] = NULL;
            }

            set_current_val(var, TRUE, FALSE);
            if(ps_global->prc)
                ps_global->prc->outstanding_pinerc_changes = 1;

            if(ps_global->keywords)
                free_keyword_list(&ps_global->keywords);

            if(var->current_val.l && var->current_val.l[0])
                ps_global->keywords = init_keyword_list(var->current_val.l);

            clear_index_cache(ps_global->mail_stream, 0);

            rv = 1;
        }
    }

    ps->mangled_screen = 1;

    return(rv);
}