%{

/*
 * +-------------------------------------------------------+
 * |                                                       |
 * |     videogen                                          |
 * |                                                       |
 * |     a simple XFree86 Modeline calculator              |
 * |     (c) 1997-2003, Szabolcs Rumi                      |   
 * |                                                       |
 * |     http://www.dynaweb.hu/opensource/videogen         |
 * |                                                       |
 * |     the videogen package is distributed under the     |
 * |     GNU General Public License Version 2 (GPLv2)      |
 * |                                                       |
 * +-------------------------------------------------------+   
 */





#include <stdio.h>
#include <stdlib.h>

#include "config.h"
#include "videogen.h"



extern unsigned int lexer_num_lines;	/* line counter */
extern int yylex (void);
void yyerror (char *errtext);





%}





%union {
	long int ival;		/* integer value */
	double fval;		/* floating point value */
	unsigned char bval;	/* boolean value */
}

%token <ival> T_INTEGER
%token <fval> T_FLOAT
%token <bval> T_BOOLEAN
%token T_VERBOSE
%token T_FBSET
%token T_NVIDIA
%token T_MODE
%token T_MAX_DOTCLK
%token T_MAX_HFREQ
%token T_MAX_VFREQ
%token T_DESIRED_VFREQ
%token T_HVISIBLE
%token T_VVISIBLE
%token T_HFPORCH
%token T_HBPORCH
%token T_HSYNC
%token T_VFPORCH
%token T_VBPORCH
%token T_VSYNC





%%





input:		/* empty */				/* empty */
		| input line				/* empty */
		| input error				/* empty */
;



line:		'\n'					/* empty */
		| assignments '\n'			/* empty */
;



assignments:	';'					/* empty */
		| assignments ';' assignment		/* empty */
		| assignments ';' 			/* empty */
		| assignment				/* empty */
;



assignment:	T_VERBOSE '=' T_BOOLEAN			{
							
	if ($3 > 0)
	{
		if (commit_verbose (CFG_PREC_CFGFILE, &verbose, 1) == 0) {
			pmsg (VL_DEBUG, "[cfgfile] line %u: verbose mode on\n", lexer_num_lines);
		}
	}
	else
	{
		if (commit_verbose (CFG_PREC_CFGFILE, &verbose, 0) == 0)
			pmsg (VL_DEBUG, "[cfgfile] line %u: verbose mode off\n", lexer_num_lines);
	}

							}



		| T_FBSET '=' T_BOOLEAN			{
							
	if ($3 > 0)
	{
		if (commit_fbset (CFG_PREC_CFGFILE, &fbset, 1) == 0)
			pmsg (VL_DEBUG, "[cfgfile] line %u: fbset mode on\n", lexer_num_lines);
	}
	else
	{
		if (commit_fbset (CFG_PREC_CFGFILE, &fbset, 0) == 0)
			pmsg (VL_DEBUG, "[cfgfile] line %u: fbset mode off\n", lexer_num_lines);
	}

							}



		| T_NVIDIA '=' T_BOOLEAN		{
							
	if ($3 > 0)
	{
		if (commit_nvidia (CFG_PREC_CFGFILE, &nvidia, 1) == 0)
			pmsg (VL_DEBUG, "[cfgfile] line %u: nvidia compatibility mode on\n", lexer_num_lines);
	}
	else
	{
		if (commit_nvidia (CFG_PREC_CFGFILE, &nvidia, 0) == 0)
			pmsg (VL_DEBUG, "[cfgfile] line %u: nvidia compatibility mode off\n", lexer_num_lines);
	}

							}



		| T_MODE T_INTEGER 'x' T_INTEGER	{
							
	switch (commit_mode (CFG_PREC_CFGFILE, &modes, &num_modes, $2, $4))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: added mode %lux%lu\n", lexer_num_lines, $2, $4);
				break;
			}

		case 5: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: too many modes, dropping %lux%lu\n", lexer_num_lines, $2, $4);
				pmsg (VL_VERBOSE, "no more than 256 modes are allowed, dropping %lux%lu\n", $2, $4);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter %lux%lu\n", lexer_num_lines, $2, $4);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}



		| T_MAX_DOTCLK '=' T_INTEGER		{
	
	switch (commit_max_dotclk (CFG_PREC_CFGFILE, &max_dotclk, $3))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: max_dotclk = %lu MHz\n", lexer_num_lines, $3);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter (max_dotclk = %lu MHz)\n", lexer_num_lines, $3);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}



		| T_MAX_DOTCLK '=' T_FLOAT		{
	
	switch (commit_max_dotclk (CFG_PREC_CFGFILE, &max_dotclk, $3))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: max_dotclk = %f MHz\n", lexer_num_lines, $3);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter (max_dotclk = %f MHz)\n", lexer_num_lines, $3);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}



		| T_MAX_HFREQ '=' T_INTEGER		{
	
	switch (commit_max_hfreq (CFG_PREC_CFGFILE, &max_hfreq, $3))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: max_hfreq = %lu kHz\n", lexer_num_lines, $3);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter (max_hfreq = %lu kHz)\n", lexer_num_lines, $3);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}



		| T_MAX_HFREQ '=' T_FLOAT		{
	
	switch (commit_max_hfreq (CFG_PREC_CFGFILE, &max_hfreq, $3))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: max_hfreq = %f kHz\n", lexer_num_lines, $3);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter (max_hfreq = %f kHz)\n", lexer_num_lines, $3);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}



		| T_MAX_VFREQ '=' T_INTEGER		{
	
	switch (commit_max_vfreq (CFG_PREC_CFGFILE, &max_vfreq, $3))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: max_vfreq = %lu Hz\n", lexer_num_lines, $3);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter (max_vfreq = %lu Hz)\n", lexer_num_lines, $3);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}



		| T_MAX_VFREQ '=' T_FLOAT		{
		
	switch (commit_max_vfreq (CFG_PREC_CFGFILE, &max_vfreq, $3))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: max_vfreq = %f Hz\n", lexer_num_lines, $3);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter (max_vfreq = %f Hz)\n", lexer_num_lines, $3);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}



		| T_DESIRED_VFREQ '=' T_INTEGER		{
	
	switch (commit_desired_vfreq (CFG_PREC_CFGFILE, &desired_vfreq, $3))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: desired_vfreq = %lu Hz\n", lexer_num_lines, $3);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter (desired_vfreq = %lu Hz)\n", lexer_num_lines, $3);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}



		| T_DESIRED_VFREQ '=' T_FLOAT		{
	
	switch (commit_desired_vfreq (CFG_PREC_CFGFILE, &desired_vfreq, $3))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: desired_vfreq = %f Hz\n", lexer_num_lines, $3);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter (desired_vfreq = %f Hz)\n", lexer_num_lines, $3);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}



		| T_HVISIBLE '=' T_INTEGER		{
	
	switch (commit_hvisible (CFG_PREC_CFGFILE, &hvisible, $3))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: hvisible = %lu%%\n", lexer_num_lines, $3);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter (hvisible = %lu%%)\n", lexer_num_lines, $3);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}



		| T_HVISIBLE '=' T_FLOAT		{
		
	switch (commit_hvisible (CFG_PREC_CFGFILE, &hvisible, $3))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: hvisible = %.4g%%\n", lexer_num_lines, $3);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter (hvisible = %.4g%%)\n", lexer_num_lines, $3);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}



		| T_VVISIBLE '=' T_INTEGER		{
	
	switch (commit_vvisible (CFG_PREC_CFGFILE, &vvisible, $3))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: vvisible = %lu%%\n", lexer_num_lines, $3);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter (vvisible = %lu%%)\n", lexer_num_lines, $3);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}



		| T_VVISIBLE '=' T_FLOAT		{
	
	switch (commit_vvisible (CFG_PREC_CFGFILE, &vvisible, $3))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: vvisible = %.4g%%\n", lexer_num_lines, $3);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter (vvisible = %.4g%%)\n", lexer_num_lines, $3);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}



		| T_HFPORCH '=' T_INTEGER		{
	
	switch (commit_hfporch (CFG_PREC_CFGFILE, &hfporch, $3))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: hfporch = %lu ticks\n", lexer_num_lines, $3);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter (hfporch = %lu ticks\n", lexer_num_lines, $3);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}



		| T_HBPORCH '=' T_INTEGER		{
	
	switch (commit_hbporch (CFG_PREC_CFGFILE, &hbporch, $3))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: hbporch = %lu ticks\n", lexer_num_lines, $3);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter (hbporch = %lu ticks\n", lexer_num_lines, $3);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}



		| T_HSYNC '=' T_INTEGER			{
	
	switch (commit_hsync (CFG_PREC_CFGFILE, &hsync, $3))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: hsync = %lu us\n", lexer_num_lines, $3);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter (hsync = %lu us\n", lexer_num_lines, $3);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}



		| T_HSYNC '=' T_FLOAT			{
	
	switch (commit_hsync (CFG_PREC_CFGFILE, &hsync, $3))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: hsync = %.4g us\n", lexer_num_lines, $3);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter (hsync = %.4g us\n", lexer_num_lines, $3);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}



		| T_VFPORCH '=' T_INTEGER		{
	
	switch (commit_vfporch (CFG_PREC_CFGFILE, &vfporch, $3))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: vfporch = %lu ticks\n", lexer_num_lines, $3);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter (vfporch = %lu ticks\n", lexer_num_lines, $3);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}



		| T_VBPORCH '=' T_INTEGER		{
	
	switch (commit_vbporch (CFG_PREC_CFGFILE, &vbporch, $3))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: vbporch = %lu ticks\n", lexer_num_lines, $3);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter (vbporch = %lu ticks\n", lexer_num_lines, $3);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}

							

		| T_VSYNC '=' T_INTEGER			{
	
	switch (commit_vsync (CFG_PREC_CFGFILE, &vsync, $3))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: vsync = %lu us\n", lexer_num_lines, $3);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter (vsync = %lu us\n", lexer_num_lines, $3);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}



		| T_VSYNC '=' T_FLOAT			{
	
	switch (commit_vsync (CFG_PREC_CFGFILE, &vsync, $3))
	{
		case -1:	break;

		case 0:	{
				pmsg (VL_DEBUG, "[cfgfile] line %u: vsync = %.4g us\n", lexer_num_lines, $3);
				break;
			}

		default: {
				pmsg (VL_DEBUG, "[cfgfile] line %u: invalid parameter (vsync = %.4g us\n", lexer_num_lines, $3);
				pmsg (VL_VERBOSE, "error at line %u: invalid parameter\n", lexer_num_lines);
				YYABORT;
			}
	}

							}
								
;





%%





void
yyerror (char *errtext)
{
	pmsg (VL_DEBUG, "[cfgfile] parse error at line %u: %s\n", lexer_num_lines, errtext);
	pmsg (VL_VERBOSE, "error at line %u: %s\n", lexer_num_lines, errtext);
}





/* EOF */
