/* * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* * mslpd_stack.c : Handles stack operations for the mslpd_query routines. * * Version: 1.4 * Date: 03/07/99 * * Licensee will, at its expense, defend and indemnify Sun Microsystems, * Inc. ("Sun") and its licensors from and against any third party * claims, including costs and reasonable attorneys' fees, and be wholly * responsible for any liabilities arising out of or related to the * Licensee's use of the Software or Modifications. The Software is not * designed or intended for use in on-line control of aircraft, air * traffic, aircraft navigation, or aircraft communications; or in the * design, construction, operation or maintenance of any nuclear facility * and Sun disclaims any express or implied warranty of fitness for such * uses. THE SOFTWARE IS PROVIDED TO LICENSEE "AS IS" AND ALL EXPRESS OR * IMPLIED CONDITION AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF * MERCHANTABILITY, FITNESS FOR WARRANTIES, INCLUDING ANY IMPLIED * WARRANTY OF MERCHANTABILITY, FITNESS FOR PARTICULAR PURPOSE OR NON- * INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT WILL SUN BE LIABLE HEREUNDER * FOR ANY DIRECT DAMAGES OR ANY INDIRECT, PUNITIVE, SPECIAL, INCIDENTAL * OR CONSEQUENTIAL DAMAGES OF ANY KIND. * * (c) Sun Microsystems, 1998, All Rights Reserved. * Author: Erik Guttman */ /* Portions Copyright (c) 2002 Apple Computer, Inc. All rights reserved. */ #include <stdio.h> #include <assert.h> #include <string.h> #include "mslp_sd.h" #include "slp.h" #include "mslp.h" /* for LOG */ #include "mslpd_mask.h" #include "mslpd_stack.h" #define MSLPQ_INCR 50 /* * stack_init * * Creates the stack and puts the initial frame (INIT_STATE) on it. * Optimisticly assume that everything in the use mask will be true * initially. * * pmUseMask The mask generated by comparisons of srvtype, scope * list and lang (if the search filter is not null). * * Returns: * An initialized stack. */ MSLPQStack * stack_init(Mask *pmUseMask) { MSLPQStack *pstack = (MSLPQStack*) safe_malloc(sizeof(MSLPQStack)*MSLPQ_INCR,0,0); pstack->iSize = 1; pstack->iMax = MSLPQ_INCR; pstack->pframe = (MSLPQframe*) safe_malloc(sizeof(MSLPQframe)*MSLPQ_INCR,0,0); pstack->pframe[0].pmask = pmUseMask; pstack->pframe[0].state = INIT_STATE; return pstack; } /* * stack_push * * This guarantees that the stack does not overflow and pushes * state onto the top available frame. * * pstack The stack to operate on * pmask The mask to push onto the stack (note the stack OWNS this) * state The state of the parsing at the time of the stack_push * * Returns: none * * Side effect: The stack might be resized as a result of this operation. * It will remain at this increased size (there is no shrink to fit * optimization, etc.) */ void stack_push(MSLPQStack *pstack, Mask *pmask, MSLPQState state) { if ((pstack->iSize +1) == pstack->iMax) { MSLPQframe *pframe = (MSLPQframe *) safe_malloc((pstack->iMax+MSLPQ_INCR)*sizeof(MSLPQframe), (char*)pstack->pframe, pstack->iSize*sizeof(MSLPQframe)); pstack->iMax += MSLPQ_INCR; SLPFree(pstack->pframe); pstack->pframe = pframe; } pstack->pframe[pstack->iSize].state = state; pstack->pframe[pstack->iSize].pmask = pmask; pstack->iSize++; } /* * stack_pop * * The stack is popped - this will simply return the current frame, * and decrement the count. Do not free the frame itself! That must * be done by the popper! */ MSLPQframe * stack_pop(MSLPQStack *pstack) { if (pstack->iSize == 0) { LOG(SLP_LOG_ERR,"pop: query handling stack empty"); return NULL; } #ifdef TRACE_MASK printf("at pop:\n"); mask_show(pstack->pframe->pmask); #endif return &(pstack->pframe[pstack->iSize--]); } MSLPQframe * stack_curr(MSLPQStack *pstack) { assert(pstack->iSize > 0); return &(pstack->pframe[pstack->iSize - 1]); /* -1 due to 0 based array */ } MSLPQframe * stack_prev(MSLPQStack *pstack) { assert(pstack->iSize > 0); if (pstack->iSize == 1) return NULL; return &(pstack->pframe[pstack->iSize-2]); /* -2 is one less than curr */ } /* * stack_delete * * This operation is performed at the end of a query to release the memory * allocated to perform it. * * pstack The stack to be freed. * * Returns: none * * Side effect: * All masks, etc. are freed by this operation. */ void stack_delete(MSLPQStack *pstack) { int i; for (i = 0; i < pstack->iSize; i++) { if (pstack->pframe[i].pmask) mask_delete(pstack->pframe[i].pmask); } SLPFree((void*)pstack->pframe); SLPFree((void*)pstack); }