PageRenderTime 54ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/OpenSLP_1-1-5/openslp/common/slp_filter_y.y

#
Happy | 373 lines | 329 code | 44 blank | 0 comment | 0 complexity | b64d90f1cbee62a6917218319efde844 MD5 | raw file
Possible License(s): BSD-3-Clause, MPL-2.0-no-copyleft-exception, LGPL-2.1
  1. /*******************************************************************
  2. * Description: encode/decode LDAP filters
  3. *
  4. * Originated: 04-21-2001
  5. * Original Author: Mike Day - md@soft-hackle.net
  6. *
  7. * Copyright (C) Michael Day, 2001
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * as published by the Free Software Foundation; either version 2
  12. * of the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  22. *******************************************************************/
  23. %{
  24. #define yymaxdepth slp_filter_maxdepth
  25. #define yyparse slp_filter_parse
  26. #define yylex slp_filter_lex
  27. #define yyerror slp_filter_error
  28. #define yylval slp_filter_lval
  29. #define yychar slp_filter_char
  30. #define yydebug slp_filter_debug
  31. #define yypact slp_filter_pact
  32. #define yyr1 slp_filter_r1
  33. #define yyr2 slp_filter_r2
  34. #define yydef slp_filter_def
  35. #define yychk slp_filter_chk
  36. #define yypgo slp_filter_pgo
  37. #define yyact slp_filter_act
  38. #define yyexca slp_filter_exca
  39. #define yyerrflag slp_filter_errflag
  40. #define yynerrs slp_filter_nerrs
  41. #define yyps slp_filter_ps
  42. #define yypv slp_filter_pv
  43. #define yys slp_filter_s
  44. #define yy_yys slp_filter_yys
  45. #define yystate slp_filter_state
  46. #define yytmp slp_filter_tmp
  47. #define yyv slp_filter_v
  48. #define yy_yyv slp_filter_yyv
  49. #define yyval slp_filter_val
  50. #define yylloc slp_filter_lloc
  51. #define yyreds slp_filter_reds
  52. #define yytoks slp_filter_toks
  53. #define yylhs slp_filter_yylhs
  54. #define yylen slp_filter_yylen
  55. #define yydefred slp_filter_yydefred
  56. #define yydgoto slp_filter_yydgoto
  57. #define yysindex slp_filter_yysindex
  58. #define yyrindex slp_filter_yyrindex
  59. #define yygindex slp_filter_yygindex
  60. #define yytable slp_filter_yytable
  61. #define yycheck slp_filter_yycheck
  62. #define yyname slp_filter_yyname
  63. #define yyrule slp_filter_yyrule
  64. #include "slp_filter.h"
  65. #include "slp_linkedlist.h"
  66. #include <unistd.h>
  67. #include <string.h>
  68. #include <stdlib.h>
  69. #ifndef FALSE
  70. #define FALSE 0
  71. #endif
  72. #ifndef TRUE
  73. #define TRUE (!FALSE)
  74. #endif
  75. /* prototypes and globals go here */
  76. void slp_filter_close_lexer(unsigned int handle);
  77. unsigned int slp_filter_init_lexer(const char *s);
  78. int slp_filter_parse(void);
  79. int slp_filter_parse(void);
  80. void slp_filter_error(char *, ...);
  81. int slp_filter_lex(void);
  82. /* have a place to put attributes and the filter while the parser is working */
  83. /* on them makes it easier to recover from parser errors - all the memory we */
  84. /* need to free is available from the list heads below. */
  85. /* listhead for reduced filters until the parser is finished */
  86. static filterHead reducedFilters = { &reducedFilters, &reducedFilters, TRUE } ;
  87. static int nesting_level;
  88. %}
  89. /* definitions for ytab.h */
  90. %union {
  91. int filter_int;
  92. char *filter_string;
  93. SLPLDAPFilter *filter_filter;
  94. }
  95. %token<filter_int> L_PAREN R_PAREN OP_AND OP_OR OP_NOT OP_EQU OP_GT OP_LT OP_PRESENT OP_APPROX
  96. %token<filter_int> VAL_INT VAL_BOOL
  97. %token<filter_string> OPERAND
  98. /* typecast the non-terminals */
  99. %type <filter_filter> filter filter_list expression
  100. %type <filter_int> exp_operator filter_op filter_open filter_close
  101. %%
  102. /* grammar */
  103. filter_list: filter | filter_list filter ;
  104. filter: filter_open filter_op filter_list filter_close
  105. {
  106. if(NULL != ($$ = SLPAllocFilter($2)))
  107. {
  108. $$->nestingLevel = nesting_level;
  109. if(!SLP_IS_EMPTY(&reducedFilters) )
  110. {
  111. SLPLDAPFilter *temp = (SLPLDAPFilter *)reducedFilters.next;
  112. while(!SLP_IS_HEAD(temp))
  113. {
  114. if(temp->nestingLevel == nesting_level + 1)
  115. {
  116. SLPLDAPFilter *nest = temp;
  117. temp = temp->next;
  118. SLP_UNLINK(nest);
  119. SLP_INSERT_BEFORE(nest, (SLPLDAPFilter *)&($$->children)) ;
  120. }
  121. else
  122. {
  123. temp = temp->next;
  124. }
  125. }
  126. SLP_INSERT_BEFORE( (filterHead *)$$, &reducedFilters);
  127. }
  128. else
  129. {
  130. SLPFreeFilter($$) ; $$ = NULL ;
  131. }
  132. }
  133. }
  134. | filter_open expression filter_close
  135. {
  136. $$ = $2;
  137. if($2 != NULL)
  138. {
  139. $2->nestingLevel = nesting_level;
  140. SLP_INSERT_BEFORE((filterHead *)$2, &reducedFilters) ;
  141. }
  142. };
  143. filter_open: L_PAREN
  144. {
  145. nesting_level++;
  146. };
  147. filter_close: R_PAREN
  148. {
  149. nesting_level--;
  150. };
  151. filter_op: OP_AND | OP_OR | OP_NOT
  152. {
  153. $$ = yylval.filter_int;
  154. };
  155. expression: OPERAND OP_PRESENT
  156. { /* presence test binds to single operand */
  157. if(NULL != ($$ = SLPAllocFilter(expr_present)))
  158. {
  159. SLPAttrList *attr = SLPAllocAttr($1, string, "*", (int)strlen("*") + 1);
  160. if(attr != NULL)
  161. {
  162. SLP_INSERT(attr, &($$->attrs));
  163. }
  164. else
  165. {
  166. SLPFreeFilter($$); $$ = NULL;
  167. }
  168. }
  169. }
  170. | OPERAND exp_operator VAL_INT
  171. { /* must be an int or a bool */
  172. /* remember to touch up the token values to match the enum in SLP.h */
  173. if(NULL != ($$ = SLPAllocFilter($2)))
  174. {
  175. SLPAttrList *attr = SLPAllocAttr($1, integer, &($3), sizeof($3));
  176. if(attr != NULL)
  177. {
  178. SLP_INSERT(attr, &($$->attrs));
  179. }
  180. else
  181. {
  182. SLPFreeFilter($$); $$ = NULL ;
  183. }
  184. }
  185. }
  186. | OPERAND exp_operator VAL_BOOL
  187. { /* must be an int or a bool */
  188. /* remember to touch up the token values to match the enum in SLP.h */
  189. if(NULL != ($$ = SLPAllocFilter($2)))
  190. {
  191. SLPAttrList *attr = SLPAllocAttr($1, boolean, &($3), sizeof($3));
  192. if(attr != NULL)
  193. {
  194. SLP_INSERT(attr, &($$->attrs));
  195. }
  196. else
  197. {
  198. SLPFreeFilter($$); $$ = NULL ;
  199. }
  200. }
  201. }
  202. | OPERAND exp_operator OPERAND
  203. { /* both operands are strings */
  204. if(NULL != ($$ = SLPAllocFilter($2)))
  205. {
  206. SLPAttrList *attr = SLPAllocAttr($1, string, $3, (int)strlen($3) + 1 );
  207. if(attr != NULL)
  208. {
  209. SLP_INSERT(attr, &($$->attrs));
  210. }
  211. else
  212. {
  213. SLPFreeFilter($$); $$ = NULL ;
  214. }
  215. }
  216. };
  217. exp_operator: OP_EQU | OP_GT | OP_LT | OP_APPROX
  218. {
  219. $$ = yylval.filter_int;
  220. };
  221. %%
  222. SLPLDAPFilter *SLPAllocFilter(int operator)
  223. {
  224. SLPLDAPFilter *filter = (SLPLDAPFilter *)calloc(1, sizeof(SLPLDAPFilter));
  225. if ( filter != NULL )
  226. {
  227. filter->next = filter->prev = filter;
  228. if ( operator == head )
  229. {
  230. filter->isHead = TRUE;
  231. }
  232. else
  233. {
  234. filter->children.next = filter->children.prev = &(filter->children);
  235. filter->children.isHead = 1;
  236. filter->attrs.next = filter->attrs.prev = &(filter->attrs);
  237. filter->attrs.isHead = 1;
  238. filter->operator = operator;
  239. }
  240. }
  241. return(filter);
  242. }
  243. void SLPFreeFilter(SLPLDAPFilter *filter)
  244. {
  245. if ( filter->children.next != NULL )
  246. {
  247. while ( ! (SLP_IS_EMPTY((SLPLDAPFilter *)&(filter->children))) )
  248. {
  249. SLPLDAPFilter *child = (SLPLDAPFilter *)filter->children.next;
  250. SLP_UNLINK(child);
  251. SLPFreeFilter(child);
  252. }
  253. }
  254. if ( filter->attrs.next != NULL )
  255. {
  256. while ( ! (SLP_IS_EMPTY(&(filter->attrs))) )
  257. {
  258. SLPAttrList *attrs = filter->attrs.next;
  259. SLP_UNLINK(attrs);
  260. SLPFreeAttr(attrs);
  261. }
  262. }
  263. }
  264. void SLPFreeFilterList(SLPLDAPFilter *head, int static_flag)
  265. {
  266. while ( ! (SLP_IS_EMPTY(head)) )
  267. {
  268. SLPLDAPFilter *temp = head->next;
  269. SLP_UNLINK(temp);
  270. SLPFreeFilter(temp);
  271. }
  272. if ( static_flag == TRUE )
  273. SLPFreeFilter(head);
  274. return;
  275. }
  276. void SLPFreeFilterTree(SLPLDAPFilter *root)
  277. {
  278. if ( !SLP_IS_EMPTY( &(root->children) ) )
  279. {
  280. SLPFreeFilterTree((SLPLDAPFilter *)root->children.next);
  281. }
  282. if ( ! (SLP_IS_HEAD(root->next)) && (!SLP_IS_EMPTY(root->next)) )
  283. {
  284. SLPFreeFilterTree(root->next);
  285. }
  286. if ( root->attrs.next != NULL )
  287. {
  288. while ( ! (SLP_IS_EMPTY(&(root->attrs))) )
  289. {
  290. SLPAttrList *attrs = root->attrs.next;
  291. SLP_UNLINK(attrs);
  292. SLPFreeAttr(attrs);
  293. }
  294. }
  295. }
  296. void SLPInitFilterList(void )
  297. {
  298. reducedFilters.next = reducedFilters.prev = &reducedFilters;
  299. reducedFilters.isHead = TRUE;
  300. return;
  301. }
  302. void SLPCleanUpFilterList(void)
  303. {
  304. SLPFreeFilterList( (SLPLDAPFilter *)&reducedFilters, FALSE);
  305. }
  306. SLPLDAPFilter *SLPDecodeLDAPFilter(const char *filter)
  307. {
  308. SLPLDAPFilter *temp = NULL;
  309. unsigned int lexer = 0;
  310. SLPInitFilterList();
  311. nesting_level = 1;
  312. if ( 0 != (lexer = slp_filter_init_lexer(filter)) )
  313. {
  314. if ( slp_filter_parse() )
  315. {
  316. SLPCleanUpFilterList();
  317. }
  318. slp_filter_close_lexer(lexer);
  319. }
  320. if ( !SLP_IS_EMPTY(&reducedFilters) )
  321. {
  322. if ( NULL != (temp = SLPAllocFilter(ldap_and)) )
  323. {
  324. SLP_LINK_HEAD(&(temp->children), &reducedFilters);
  325. }
  326. }
  327. SLPCleanUpFilterList();
  328. return(temp);
  329. }