ibConfYacc.y 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. %{
  2. #include <stdio.h>
  3. #include "ib_internal.h"
  4. #undef EXTERN
  5. #include "ibP.h"
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #include "ibConfYacc.h"
  9. #include "ibConfLex.h"
  10. #define YYERROR_VERBOSE
  11. YY_DECL;
  12. #define YYPARSE_PARAM parse_arg
  13. #define YYLEX_PARAM priv(YYPARSE_PARAM)->yyscanner
  14. typedef struct
  15. {
  16. yyscan_t yyscanner;
  17. ibConf_t *configs;
  18. unsigned int configs_length;
  19. unsigned int config_index;
  20. ibBoard_t *boards;
  21. unsigned int boards_length;
  22. int board_index;
  23. }gpib_yyparse_private_t;
  24. static inline gpib_yyparse_private_t* priv( gpib_yyparse_private_t *parse_arg )
  25. {
  26. return parse_arg;
  27. }
  28. static inline ibConf_t* current_config( gpib_yyparse_private_t *parse_arg )
  29. {
  30. return &parse_arg->configs[ parse_arg->config_index ];
  31. }
  32. static inline ibBoard_t* current_board( gpib_yyparse_private_t *parse_arg )
  33. {
  34. if( parse_arg->board_index < 0 ) return NULL;
  35. return &parse_arg->boards[ parse_arg->board_index ];
  36. }
  37. void init_gpib_yyparse_private( gpib_yyparse_private_t *priv )
  38. {
  39. priv->yyscanner = 0;
  40. priv->configs = NULL;
  41. priv->configs_length = 0;
  42. priv->config_index = 0;
  43. priv->boards = NULL;
  44. priv->boards_length = 0;
  45. priv->board_index = -1;
  46. }
  47. int parse_gpib_conf( const char *filename, ibConf_t *configs, unsigned int configs_length,
  48. ibBoard_t *boards, unsigned int boards_length )
  49. {
  50. FILE *infile;
  51. int retval = 0;
  52. int i;
  53. gpib_yyparse_private_t priv;
  54. if( ( infile = fopen( filename, "r" ) ) == NULL )
  55. {
  56. fprintf(stderr, "failed to open configuration file\n");
  57. setIberr( EDVR );
  58. setIbcnt( errno );
  59. return -1;
  60. }
  61. init_gpib_yyparse_private( &priv );
  62. priv.configs = configs;
  63. priv.configs_length = configs_length;
  64. priv.boards = boards;
  65. priv.boards_length = boards_length;
  66. for( i = 0; i < priv.configs_length; i++ )
  67. {
  68. init_ibconf( &priv.configs[ i ] );
  69. }
  70. for( i = 0; i < priv.boards_length; i++ )
  71. {
  72. init_ibboard( &priv.boards[ i ] );
  73. }
  74. gpib_yylex_init(&priv.yyscanner);
  75. gpib_yyrestart(infile, priv.yyscanner);
  76. if(gpib_yyparse(&priv))
  77. {
  78. fprintf(stderr, "libgpib: failed to parse configuration file\n");
  79. //XXX setIberr()
  80. retval = -1 ;
  81. }
  82. gpib_yylex_destroy(priv.yyscanner);
  83. fclose(infile);
  84. if( retval == 0 )
  85. {
  86. for(i = 0; i < priv.configs_length && priv.configs[ i ].defaults.board >= 0; i++)
  87. {
  88. priv.configs[ i ].settings = priv.configs[ i ].defaults;
  89. }
  90. }
  91. return retval;
  92. }
  93. %}
  94. %pure_parser
  95. %union
  96. {
  97. int ival;
  98. char *sval;
  99. char bval;
  100. char cval;
  101. }
  102. %token T_INTERFACE T_DEVICE T_NAME T_MINOR T_BASE T_IRQ T_DMA
  103. %token T_PAD T_SAD T_TIMO T_EOSBYTE T_BOARD_TYPE T_PCI_BUS T_PCI_SLOT
  104. %token T_REOS T_BIN T_INIT_S T_DCL T_XEOS T_EOT
  105. %token T_MASTER T_LLO T_EXCL T_INIT_F T_AUTOPOLL
  106. %token T_NUMBER T_STRING T_BOOL T_TIVAL
  107. %type <ival> T_NUMBER
  108. %type <ival> T_TIVAL
  109. %type <sval> T_STRING
  110. %type <bval> T_BOOL
  111. %%
  112. input: /* empty */
  113. | device input
  114. | interface input
  115. | error
  116. {
  117. fprintf(stderr, "input error on line %i of %s\n", gpib_yyget_lineno(priv(parse_arg)->yyscanner), DEFAULT_CONFIG_FILE);
  118. YYABORT;
  119. }
  120. ;
  121. interface: T_INTERFACE '{' minor parameter '}'
  122. {
  123. current_config( parse_arg )->is_interface = 1;
  124. if( ++( priv(parse_arg)->config_index ) >= priv(parse_arg)->configs_length )
  125. {
  126. fprintf(stderr, " too many devices in config file\n");
  127. YYERROR;
  128. }
  129. }
  130. ;
  131. minor : T_MINOR '=' T_NUMBER {
  132. priv(parse_arg)->board_index = $3;
  133. current_config(parse_arg)->defaults.board = $3;
  134. if(priv(parse_arg)->board_index < priv(parse_arg)->boards_length )
  135. snprintf(current_board(parse_arg)->device, sizeof(current_board( parse_arg )->device), "/dev/gpib%i", priv(parse_arg)->board_index);
  136. else
  137. YYERROR;
  138. }
  139. ;
  140. parameter: /* empty */
  141. | statement parameter
  142. | error
  143. {
  144. fprintf(stderr, "parameter error on line %i of %s\n", @1.first_line, DEFAULT_CONFIG_FILE);
  145. YYERROR;
  146. }
  147. ;
  148. statement: T_PAD '=' T_NUMBER { current_config( parse_arg )->defaults.pad = $3;}
  149. | T_SAD '=' T_NUMBER { current_config( parse_arg )->defaults.sad = $3 - sad_offset;}
  150. | T_EOSBYTE '=' T_NUMBER { current_config( parse_arg )->defaults.eos = $3;}
  151. | T_REOS T_BOOL { current_config( parse_arg )->defaults.eos_flags |= $2 * REOS;}
  152. | T_BIN T_BOOL { current_config( parse_arg )->defaults.eos_flags |= $2 * BIN;}
  153. | T_REOS '=' T_BOOL { current_config( parse_arg )->defaults.eos_flags |= $3 * REOS;}
  154. | T_XEOS '=' T_BOOL { current_config( parse_arg )->defaults.eos_flags |= $3 * XEOS;}
  155. | T_BIN '=' T_BOOL { current_config( parse_arg )->defaults.eos_flags |= $3 * BIN;}
  156. | T_EOT '=' T_BOOL { current_config( parse_arg )->defaults.send_eoi = $3;}
  157. | T_TIMO '=' T_TIVAL { current_config( parse_arg )->defaults.usec_timeout = $3; }
  158. | T_TIMO '=' T_NUMBER { current_config( parse_arg )->defaults.usec_timeout = timeout_to_usec( $3 ); }
  159. | T_BASE '=' T_NUMBER { current_board( parse_arg )->base = $3; }
  160. | T_IRQ '=' T_NUMBER { current_board( parse_arg )->irq = $3; }
  161. | T_DMA '=' T_NUMBER { current_board( parse_arg )->dma = $3; }
  162. | T_PCI_BUS '=' T_NUMBER { current_board( parse_arg )->pci_bus = $3; }
  163. | T_PCI_SLOT '=' T_NUMBER { current_board( parse_arg )->pci_slot = $3; }
  164. | T_MASTER T_BOOL { current_board( parse_arg )->is_system_controller = $2; }
  165. | T_MASTER '=' T_BOOL { current_board( parse_arg )->is_system_controller = $3; }
  166. | T_BOARD_TYPE '=' T_STRING
  167. {
  168. strncpy(current_board( parse_arg )->board_type, $3,
  169. sizeof(current_board( parse_arg )->board_type));
  170. }
  171. | T_NAME '=' T_STRING
  172. {
  173. strncpy(current_config( parse_arg )->name, $3,
  174. sizeof(current_config( parse_arg )->name));
  175. }
  176. ;
  177. device: T_DEVICE '{' option '}'
  178. {
  179. current_config( parse_arg )->is_interface = 0;
  180. if( ++( priv(parse_arg)->config_index ) >= priv(parse_arg)->configs_length )
  181. {
  182. fprintf(stderr, "too many devices in config file\n");
  183. YYERROR;
  184. }
  185. }
  186. ;
  187. option: /* empty */
  188. | assign option
  189. | error
  190. {
  191. fprintf(stderr, "option error on line %i of config file\n", @1.first_line );
  192. YYERROR;
  193. }
  194. ;
  195. assign:
  196. T_PAD '=' T_NUMBER { current_config( parse_arg )->defaults.pad = $3; }
  197. | T_SAD '=' T_NUMBER { current_config( parse_arg )->defaults.sad = $3 - sad_offset; }
  198. | T_INIT_S '=' T_STRING { strncpy(current_config( parse_arg )->init_string,$3,60); }
  199. | T_EOSBYTE '=' T_NUMBER { current_config( parse_arg )->defaults.eos = $3; }
  200. | T_REOS T_BOOL { current_config( parse_arg )->defaults.eos_flags |= $2 * REOS;}
  201. | T_REOS '=' T_BOOL { current_config( parse_arg )->defaults.eos_flags |= $3 * REOS;}
  202. | T_XEOS '=' T_BOOL { current_config( parse_arg )->defaults.eos_flags |= $3 * XEOS;}
  203. | T_BIN T_BOOL { current_config( parse_arg )->defaults.eos_flags |= $2 * BIN; }
  204. | T_BIN '=' T_BOOL { current_config( parse_arg )->defaults.eos_flags |= $3 * BIN; }
  205. | T_EOT '=' T_BOOL { current_config( parse_arg )->defaults.send_eoi = $3;}
  206. | T_AUTOPOLL { current_config( parse_arg )->flags |= CN_AUTOPOLL; }
  207. | T_INIT_F '=' flags
  208. | T_NAME '=' T_STRING { strncpy(current_config( parse_arg )->name,$3, sizeof(current_config( parse_arg )->name));}
  209. | T_MINOR '=' T_NUMBER { current_config( parse_arg )->defaults.board = $3;}
  210. | T_TIMO '=' T_TIVAL { current_config( parse_arg )->defaults.usec_timeout = $3; }
  211. | T_TIMO '=' T_NUMBER { current_config( parse_arg )->defaults.usec_timeout = timeout_to_usec( $3 ); }
  212. ;
  213. flags: /* empty */
  214. | ',' flags
  215. | oneflag flags
  216. ;
  217. oneflag: T_LLO { current_config( parse_arg )->flags |= CN_SLLO; }
  218. | T_DCL { current_config( parse_arg )->flags |= CN_SDCL; }
  219. | T_EXCL { current_config( parse_arg )->flags |= CN_EXCLUSIVE; }
  220. ;
  221. %%
  222. void yyerror(char *s)
  223. {
  224. fprintf(stderr, "%s\n", s);
  225. }