PageRenderTime 106ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/2.0.beta2/openslp/common/slp_filter_y.y

#
Happy | 382 lines | 346 code | 36 blank | 0 comment | 0 complexity | 3349a890fad2f86c1fff3d9ae67b49e0 MD5 | raw file
Possible License(s): BSD-3-Clause, MPL-2.0-no-copyleft-exception, LGPL-2.1
  1. /*-------------------------------------------------------------------------
  2. * Copyright (C) 2000-2005 Mike Day <ncmike@ncultra.org>
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. *
  9. * Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. *
  12. * Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. *
  16. * Neither the name of Caldera Systems nor the names of its
  17. * contributors may be used to endorse or promote products derived
  18. * from this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CALDERA
  24. * SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  28. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. *-------------------------------------------------------------------------*/
  32. /** Bison parser input file for LDAPv3 search filter code.
  33. *
  34. * @file slp_filter_y.y
  35. * @date 04-21-2001
  36. * @author Matthew Peterson, Michael Day (md@soft-hackle.net),
  37. * John Calcote (jcalcote@novell.com)
  38. * @attention Please submit patches to http://www.openslp.org
  39. * @ingroup CommonCodeFilter
  40. */
  41. %{
  42. #define yymaxdepth slp_filter_maxdepth
  43. #define yyparse slp_filter_parse
  44. #define yylex slp_filter_lex
  45. #define yyerror slp_filter_error
  46. #define yylval slp_filter_lval
  47. #define yychar slp_filter_char
  48. #define yydebug slp_filter_debug
  49. #define yypact slp_filter_pact
  50. #define yyr1 slp_filter_r1
  51. #define yyr2 slp_filter_r2
  52. #define yydef slp_filter_def
  53. #define yychk slp_filter_chk
  54. #define yypgo slp_filter_pgo
  55. #define yyact slp_filter_act
  56. #define yyexca slp_filter_exca
  57. #define yyerrflag slp_filter_errflag
  58. #define yynerrs slp_filter_nerrs
  59. #define yyps slp_filter_ps
  60. #define yypv slp_filter_pv
  61. #define yys slp_filter_s
  62. #define yy_yys slp_filter_yys
  63. #define yystate slp_filter_state
  64. #define yytmp slp_filter_tmp
  65. #define yyv slp_filter_v
  66. #define yy_yyv slp_filter_yyv
  67. #define yyval slp_filter_val
  68. #define yylloc slp_filter_lloc
  69. #define yyreds slp_filter_reds
  70. #define yytoks slp_filter_toks
  71. #define yylhs slp_filter_yylhs
  72. #define yylen slp_filter_yylen
  73. #define yydefred slp_filter_yydefred
  74. #define yydgoto slp_filter_yydgoto
  75. #define yysindex slp_filter_yysindex
  76. #define yyrindex slp_filter_yyrindex
  77. #define yygindex slp_filter_yygindex
  78. #define yytable slp_filter_yytable
  79. #define yycheck slp_filter_yycheck
  80. #define yyname slp_filter_yyname
  81. #define yyrule slp_filter_yyrule
  82. #include "slp_types.h"
  83. #include "slp_filter.h"
  84. #include "slp_linkedlist.h"
  85. #ifndef FALSE
  86. # define FALSE 0
  87. #endif
  88. #ifndef TRUE
  89. # define TRUE (!FALSE)
  90. #endif
  91. /* prototypes and globals go here */
  92. void slp_filter_close_lexer(unsigned int handle);
  93. unsigned int slp_filter_init_lexer(const char *s);
  94. int slp_filter_parse(void);
  95. int slp_filter_parse(void);
  96. void slp_filter_error(char *, ...);
  97. int slp_filter_lex(void);
  98. /* have a place to put attributes and the filter while the parser is working */
  99. /* on them makes it easier to recover from parser errors - all the memory we */
  100. /* need to free is available from the list heads below. */
  101. /* listhead for reduced filters until the parser is finished */
  102. static filterHead reducedFilters = { &reducedFilters, &reducedFilters, TRUE } ;
  103. static int nesting_level;
  104. %}
  105. /* definitions for ytab.h */
  106. %union {
  107. int filter_int;
  108. char *filter_string;
  109. SLPLDAPFilter *filter_filter;
  110. }
  111. %token<filter_int> L_PAREN R_PAREN OP_AND OP_OR OP_NOT OP_EQU OP_GT OP_LT OP_PRESENT OP_APPROX
  112. %token<filter_int> VAL_INT VAL_BOOL
  113. %token<filter_string> OPERAND
  114. /* typecast the non-terminals */
  115. %type <filter_filter> filter filter_list expression
  116. %type <filter_int> exp_operator filter_op filter_open filter_close
  117. %%
  118. /* grammar */
  119. filter_list: filter | filter_list filter ;
  120. filter: filter_open filter_op filter_list filter_close
  121. {
  122. if(0 != ($$ = SLPAllocFilter($2)))
  123. {
  124. $$->nestingLevel = nesting_level;
  125. if(!SLP_IS_EMPTY(&reducedFilters) )
  126. {
  127. SLPLDAPFilter *temp = (SLPLDAPFilter *)reducedFilters.next;
  128. while(!SLP_IS_HEAD(temp))
  129. {
  130. if(temp->nestingLevel == nesting_level + 1)
  131. {
  132. SLPLDAPFilter *nest = temp;
  133. temp = temp->next;
  134. SLP_UNLINK(nest);
  135. SLP_INSERT_BEFORE(nest, (SLPLDAPFilter *)&($$->children)) ;
  136. }
  137. else
  138. {
  139. temp = temp->next;
  140. }
  141. }
  142. SLP_INSERT_BEFORE( (filterHead *)$$, &reducedFilters);
  143. }
  144. else
  145. {
  146. SLPFreeFilter($$) ; $$ = 0 ;
  147. }
  148. }
  149. }
  150. | filter_open expression filter_close
  151. {
  152. $$ = $2;
  153. if($2 != 0)
  154. {
  155. $2->nestingLevel = nesting_level;
  156. SLP_INSERT_BEFORE((filterHead *)$2, &reducedFilters) ;
  157. }
  158. };
  159. filter_open: L_PAREN
  160. {
  161. nesting_level++;
  162. };
  163. filter_close: R_PAREN
  164. {
  165. nesting_level--;
  166. };
  167. filter_op: OP_AND | OP_OR | OP_NOT
  168. {
  169. $$ = yylval.filter_int;
  170. };
  171. expression: OPERAND OP_PRESENT
  172. { /* presence test binds to single operand */
  173. if(0 != ($$ = SLPAllocFilter(expr_present)))
  174. {
  175. SLPAttrList *attr = SLPAllocAttr($1, string, "*", (int)strlen("*") + 1);
  176. if(attr != 0)
  177. {
  178. SLP_INSERT(attr, &($$->attrs));
  179. }
  180. else
  181. {
  182. SLPFreeFilter($$); $$ = 0;
  183. }
  184. }
  185. }
  186. | OPERAND exp_operator VAL_INT
  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(0 != ($$ = SLPAllocFilter($2)))
  190. {
  191. SLPAttrList *attr = SLPAllocAttr($1, integer, &($3), sizeof($3));
  192. if(attr != 0)
  193. {
  194. SLP_INSERT(attr, &($$->attrs));
  195. }
  196. else
  197. {
  198. SLPFreeFilter($$); $$ = 0 ;
  199. }
  200. }
  201. }
  202. | OPERAND exp_operator VAL_BOOL
  203. { /* must be an int or a bool */
  204. /* remember to touch up the token values to match the enum in SLP.h */
  205. if(0 != ($$ = SLPAllocFilter($2)))
  206. {
  207. SLPAttrList *attr = SLPAllocAttr($1, boolean, &($3), sizeof($3));
  208. if(attr != 0)
  209. {
  210. SLP_INSERT(attr, &($$->attrs));
  211. }
  212. else
  213. {
  214. SLPFreeFilter($$); $$ = 0 ;
  215. }
  216. }
  217. }
  218. | OPERAND exp_operator OPERAND
  219. { /* both operands are strings */
  220. if(0 != ($$ = SLPAllocFilter($2)))
  221. {
  222. SLPAttrList *attr = SLPAllocAttr($1, string, $3, (int)strlen($3) + 1 );
  223. if(attr != 0)
  224. {
  225. SLP_INSERT(attr, &($$->attrs));
  226. }
  227. else
  228. {
  229. SLPFreeFilter($$); $$ = 0 ;
  230. }
  231. }
  232. };
  233. exp_operator: OP_EQU | OP_GT | OP_LT | OP_APPROX
  234. {
  235. $$ = yylval.filter_int;
  236. };
  237. %%
  238. SLPLDAPFilter *SLPAllocFilter(int operator)
  239. {
  240. SLPLDAPFilter *filter = (SLPLDAPFilter *)calloc(1, sizeof(SLPLDAPFilter));
  241. if ( filter != 0 )
  242. {
  243. filter->next = filter->prev = filter;
  244. if ( operator == head )
  245. {
  246. filter->isHead = TRUE;
  247. }
  248. else
  249. {
  250. filter->children.next = filter->children.prev = &(filter->children);
  251. filter->children.isHead = 1;
  252. filter->attrs.next = filter->attrs.prev = &(filter->attrs);
  253. filter->attrs.isHead = 1;
  254. filter->operator = operator;
  255. }
  256. }
  257. return(filter);
  258. }
  259. void SLPFreeFilter(SLPLDAPFilter *filter)
  260. {
  261. if ( filter->children.next != 0 )
  262. {
  263. while ( ! (SLP_IS_EMPTY((SLPLDAPFilter *)&(filter->children))) )
  264. {
  265. SLPLDAPFilter *child = (SLPLDAPFilter *)filter->children.next;
  266. SLP_UNLINK(child);
  267. SLPFreeFilter(child);
  268. }
  269. }
  270. if ( filter->attrs.next != 0 )
  271. {
  272. while ( ! (SLP_IS_EMPTY(&(filter->attrs))) )
  273. {
  274. SLPAttrList *attrs = filter->attrs.next;
  275. SLP_UNLINK(attrs);
  276. SLPFreeAttr(attrs);
  277. }
  278. }
  279. }
  280. void SLPFreeFilterList(SLPLDAPFilter *head, int static_flag)
  281. {
  282. while ( ! (SLP_IS_EMPTY(head)) )
  283. {
  284. SLPLDAPFilter *temp = head->next;
  285. SLP_UNLINK(temp);
  286. SLPFreeFilter(temp);
  287. }
  288. if ( static_flag == TRUE )
  289. SLPFreeFilter(head);
  290. return;
  291. }
  292. void SLPFreeFilterTree(SLPLDAPFilter *root)
  293. {
  294. if ( !SLP_IS_EMPTY( &(root->children) ) )
  295. {
  296. SLPFreeFilterTree((SLPLDAPFilter *)root->children.next);
  297. }
  298. if ( ! (SLP_IS_HEAD(root->next)) && (!SLP_IS_EMPTY(root->next)) )
  299. {
  300. SLPFreeFilterTree(root->next);
  301. }
  302. if ( root->attrs.next != 0 )
  303. {
  304. while ( ! (SLP_IS_EMPTY(&(root->attrs))) )
  305. {
  306. SLPAttrList *attrs = root->attrs.next;
  307. SLP_UNLINK(attrs);
  308. SLPFreeAttr(attrs);
  309. }
  310. }
  311. }
  312. void SLPInitFilterList(void )
  313. {
  314. reducedFilters.next = reducedFilters.prev = &reducedFilters;
  315. reducedFilters.isHead = TRUE;
  316. return;
  317. }
  318. void SLPCleanUpFilterList(void)
  319. {
  320. SLPFreeFilterList( (SLPLDAPFilter *)&reducedFilters, FALSE);
  321. }
  322. SLPLDAPFilter *SLPDecodeLDAPFilter(const char *filter)
  323. {
  324. SLPLDAPFilter *temp = 0;
  325. unsigned int lexer = 0;
  326. SLPInitFilterList();
  327. nesting_level = 1;
  328. if ( 0 != (lexer = slp_filter_init_lexer(filter)) )
  329. {
  330. if ( slp_filter_parse() )
  331. {
  332. SLPCleanUpFilterList();
  333. }
  334. slp_filter_close_lexer(lexer);
  335. }
  336. if ( !SLP_IS_EMPTY(&reducedFilters) )
  337. {
  338. if ( 0 != (temp = SLPAllocFilter(ldap_and)) )
  339. {
  340. SLP_LINK_HEAD(&(temp->children), &reducedFilters);
  341. }
  342. }
  343. SLPCleanUpFilterList();
  344. return temp;
  345. }
  346. /*=========================================================================*/