/*
 * my_draw2 - draw a line from the current point (curx,cury) to (x2,y2) clipping the
 *         line to the viewport providing clipflag is TRUE
 */


/*
 * my_move2 - make (x,y) the current point (curx,cury)
 */


/*
 * rect - draw a rectangle using the current color and linestyle
 */


/*
 * symok - return TRUE if (x,y) lies within the currently defined window in
 *         world coordinates. used to clip symbols that bypass the clipping
 *         done in my_draw2.
 */


/*
 * histbox - draw a box of width 2*hdelta centered at x with height y starting
 *           from y = 0.0
 */


/*
 * histbox3 - draw a box of width 2*hdelta centered at y with length x starting
 *           from x = 0.0
 */


/*
 * lengthpoly - return the length of a polyline in device coords
 */


/*
 * drawpoly - draw a connected line in the current color and linestyle
 *            with nodes given by (x[],y[])
 */


/*
 * drawpolyseg - draw segments, treating each successive pairs of points
 *               as a line segment
 */


/*
 * writestr - user interface to the current device text drawing routine
 */


/*
 * draw the title, subtitle
 */


/*
   draw grid lines rather than ticmarks
 */


/*
 * draw a circle
 */


/*
 * draw the head of an arrow
 */


/*
 * draw an arrow
 */


/*
 * connect the ends of 2 vectors - for drawing
 * tidal ellipses
 */


/*
 * draw the legend at world coordinates (x,y)
 */


/*
 * initialize the graphics device device
 * return -1 if unable to open device
 */


/*!
 * Free memory allocated by a previous call to ElioGetHeader()
 * Calling this on an unallocated Header will likely result
 * in a seg fault.
 */


/*!
 * Free a previously allocated time step.
 */


/*!
 * Allocate memory for a time step given information in a valid
 * ElcircHeader.
 *
 * Returns ELIO_ERR on failure after cleaning up any current allocations.
 * Returns ELIO_OK on success.
 */


/*!
 * Print header information from a valid ElcircHeader struct.
 *
 * \param h = Previously filled in ElcircHeader.
 *
 */


/*!
 * ElioGetTimeStep: Read data for a single time step.
 *
 * Input variables:
 *
 * \param fp = Open file handle.
 * \param step = Time step to read starting from 0 to nsteps - 1.
 * \param h = Valid ElcircHeader struct.
 *
 * Output Variables:
 *
 * \param t = Valid ElcircTimeStep.
 *
 * On success returns ELIO_OK.
 *
 * On failure, returns ELIO_FSEEK_ERR or ELIO_FREAD_ERR depending
 * on the nature of the error.
 */


/*!
 * Returns the Z positions of the vertical given the elevation, e. Also
 * the bottom and surface indexes in i1 and i2. Array Zpos1 is returned
 * with the valid z values. Only values from zpos1[i1] through zpos[i2]
 * contain valid data.
 */


/*!
 * Return the surface index for a node.
 *
 * Input variables:
 *
 * \param fp = Open file handle
 * \param node = node number starting from 0.
 * \param step = Time step index starting from 0.
 * \param h = Valid ElcircHeader struct.
 */


/*!
 * Return data for a single node from one time step.
 *
 * Input variables:
 *
 * \param fp = Open file handle.
 * \param step = Time step to read starting from 0.
 * \param node = Node to read starting from 0.
 * \param h = Valid ElcircHeader struct.
 *
 * Output Variables:
 *
 * \param t = Pointer to the time for this time step, float.
 * \param it = Pointer to the current computational time step, integer.
 * \param bind = Pointer to the bottom index starting from 0.
 * \param sind = Pointer to the surface index starting from 0.
 * \param d = Pointer to an array of float values, with valid data from
 *     d[bind] through d[sind].
 *
 * Returns ELIO_OK on success.
 * Returns ELIO_FSEEK_ERR or ELIO_FREAD_ERR on error.
 *
 */


/*!
 * Extract data for a single node from one previously time step.
 * Works for 2d and 3d data, vector and scalar.
 *
 * Input variables:
 *
 * \param t = Pointer to previously read time step.
 * \param h = Pointer to valid ElcircHeader struct.
 * \param node = Node number starting from 0.
 * \param bind = Bottom index starting from 0.
 * \param sind = Surface index starting from 0.
 *
 * Output Variables:
 *
 * \param d = Pointer to array extracted from timestep struct.
 *
 * Returns ELIO_OK on success.
 *
 */


/*!
 * Get data for a single node from one time step - fills in missing data
 * values to match the old format.
 *
 * Input variables:
 *
 * \param fp = Pointer to open file handle.
 * \param step = Time step starting from 0.
 * \param node = Node number starting from 0.
 * \param h = Pointer to valid ElcircHeader struct.
 *
 * Output Variables:
 *
 * \param t = Pointer to time, float.
 * \param it = Pointer to computational time step, integer.
 * \param d = Pointer to array of return values, h.nvrt long.
 *
 * Returns ELIO_OK on success.
 * Returns ELIO_FSEEK_ERR and ELIO_FREAD_ERR on error.
 */


/*!
 * Get data for a single node from one time step should work for both
 * sigma and z-level grids.
 *
 * Input variables:
 *
 * \param fp = Pointer to open file handle.
 * \param step = Time step starting from 0.
 * \param elem = Element number.
 * \param h = Pointer to valid ElcircHeader struct.
 * \param hh = Pointer to shape function coefficients.
 *
 * Output Variables:
 *
 * \param t = Pointer to time, float.
 * \param it = Pointer to computational time step, integer.
 * \param bind = Pointer to bottom index, integer.
 * \param sind = Pointer to surface index, integer.
 * \param d = Pointer to array of return values, h.nvrt long.
 *
 * Returns ELIO_OK on success.
 * Returns ELIO_FSEEK_ERR and ELIO_FREAD_ERR on error.
 */


/*!
 * Get data for a single node from one time step for sigma grids
 *
 * Input variables:
 *
 * \param h = Pointer to valid ElcircHeader struct.
 * \param elem = Element number.
 * \param x = x of location to interpolate to.
 * \param y = y of location to interpolate to.
 * \param hh = Pointer to shape function coefficients.
 * \param t = Pointer to valid ElcircTimeStep struct.
 *
 * Output Variables:
 *
 * \param d = Pointer to array of return values, h.nvrt long.
 *
 * Returns ELIO_OK on success.
 * Returns ELIO_FSEEK_ERR and ELIO_FREAD_ERR on error.
 */


/*!
 * int ElioGetXYData(FILE * fp, int step, double x, double y, ElcircHeader * h, float *t, int *it, int *bind, int *sind, float *d)
 *
 * Get data at (x, y) by interpolation.
 *
 * \param fp - Open file handle for the file to read.
 * \param step  - Step to read starting from 0 - the first step.
 * \param x - X.
 * \param y - Y.
 * \param h - Elcirc header information previously read.
 * \param t - Return time from the file.
 * \param it - Return time step from file.
 * \param bind - Integer array of 4 values for returning bottom indexes for the element (x, y) is in.
 * \param sind - Integer array of 4 values for returning surface indexes for the element (x, y) is in.
 * \param d - Return data values.
 *
 * Returns ELIO_OK on success.
 * Returns ELIO_ERR on unknown failures.
 * Returns ELIO_FSEEK_ERR on seek failures.
 * Returns ELIO_FREAD_ERR on read failures.
 */


/*!
 *  int ElioGetPoint(FILE * fp, int step, int node, int level, ElcircHeader * h, float *t, int *it, float *d)
 * Get data for a single node from one time step at a particular level (numbered from 0)
 *
 * \param fp - Open file handle for the file to read.
 * \param step  - Step to read starting from 0 - the first step.
 * \param node  - Node to read starting from 0.
 * \param level - Level to read starting from 0.
 * \param h - Elcirc header information previously read.
 * \param t         - Return time value from data file.
 * \param it,         - Return time step from data file.
 * \param d         - Reurn data value.
 *
 * Returns ELIO_OK on success.
 * Returns ELIO_ERR on unknown failures.
 * Returns ELIO_FSEEK_ERR on seek failures.
 * Returns ELIO_FREAD_ERR on read failures.
 */


/*!
 * Read the ElcircHeader from a data file
 *
 * Input variables:
 *
 * \param fname = Pointer to a character array with the file name to read.
 *
 * Output variables:
 *
 * \param h = Pointer to ElcircHeader header. Memory will be allocated
 *     to accomodate the internal variables.
 *
 * Returns ELIO_OK on success.
 * Returns non-zero on failure.
 *
 * Notes: There are some transformations of header variables performed for
 * convenience. For 2d variables such as elevations and winds, nvrt (the
 * number of levels) is set to one, the bottom index for each node is set
 * to 0 for all nodes. In the case of 3d variables the bottom indices
 * ('bi') are decremented by one.
 *
 */


/*!
 * Allocate memory for an ElcircHeader
 *
 * Input/Output variable:
 *
 * \param h = Pointer to ElcircHeader header. Memory will be allocated
 *     to accomodate the internal variables. Assumes suitable defaults
 *     have been set for np, ne, and nvrt. Also that other variables
 *     have proper defaults set.
 *
 * Returns ELIO_OK on success.
 * Returns non-zero on failure.
 *
 */


/*!
 * Return the actual number of time steps in a data file regardless of
 * what the ElcircHeader says.
 */


/*!
 * Extract a Header for the extracted grid
 * x, y, isin need to be allocated in advance.
 * invert = 1 to select outside the region
 * most == 1 to include an element if a single node is in the region
 * NOTE: most does not work, if a node is in then every node of every element that uses that node is also in
 * Need to add some additional logic for most to work.
 */


/*!
 * Extract data from a sampled grid
 * The header must be created before this function is called
 */


/*!
 * Routines to determine if a point lies in a polygon
*/


/*!
 * Determine if (x,y) is in the polygon xlist[], ylist[].
 */


/*!
 * Locate the element in which x, y is located.
 * Returns -1 if the element cannot be located, the element number
 * starting from zero otherwise.
 *
 */


/*!
 * Determine if (x, y) is inside the triangle given by (x1, y1), (x2, y2), (x3, y3).
 */


/*!
 * Determine if (x, y) is inside the convex quadrangle given by (x1, y1), (x2, y2), (x3, y3), (x4, y4).
 */


/*!
 * Given previously computed nodal coefficients in h, and flow (u, v) at each node compute the flow and return in (uret, vret).
 *
 * \param n Integer number of nodes.
 * \param h Pointer to nodal coefficients.
 * \param u Pointer to nodal values for u at the nodes.
 * \param v Pointer to nodal values for u at the nodes.
 * \param uret Pointer to return value.
 * \param vret Pointer to return value.
 */


/*! Compute coefficients for interpolation for both triangles and quads using
 * information from the element number.
 *
 * \param h Header struct to write.
 * \param elem  Number of the element from 0.
 * \param xp X-coordinate of point for interpolation.
 * \param yp Y-coordinate of point for interpolation.
 * \param w Coefficients of interpolator.
 *
 * Returns ELIO_OK on success and ELIO_ERR on failure.
 */


/*! Compute coefficients for interpolation for both triangles and quads using
 * information from the element number.
 *
 *  \param h Header struct to write.
 *  \param elem  Number of the element from 0.
 *  \param xp X-coordinate of point for interpolation.
 *  \param yp Y-coordinate of point for interpolation.
 *  \param w Coefficients of interpolator.
 *
 *  Returns ELIO_OK on success and ELIO_ERR on failure.
 */


/*! Compute coefficients for interpolation for both triangles and quads using
 * coordinates of the nodes rather than information from the element number.
 *
 * \param n Number of nodes in the element.
 * \param x Pointer to array with x-coordinate of nodes.
 * \param y Pointer to array with y-coordinate of nodes.
 * \param xp X-coordinate of point for interpolation.
 * \param yp Y-coordinate of point for interpolation.
 * \param w Coefficients of interpolator.
 *
 * Returns ELIO_OK on success and ELIO_ERR on failure.
 */


/*!
 * Define a header for the surface.
*/


/*! Write the ELCIRC header.
 *  \param fp Pointer to open file handle.
 *  \param h Header struct to write.
 *
 *  The structure to write should be prepared in advance with an allocated
 *  grid and all members filled in with appropriate values.
 */


/*!
 * Write a time step.
 *
 * \param fp Open filehandle.
 * \param h Pointer to ELCIRC header.
 * \param t Value parameter containing time step information to write.
 */


/*! Return the file type.
 *
 * Returns -1 on error.
*/


/*!
 * Copy header h1 to h2
 */


/*!
 * Write out data to a single step .61 file
 */


/*!
 * Return the area for the given element. Element numbering starts from 0.
 *
 *  \param h - Previously read header.
 *  \param elem - Element number from 0 to compute the center.
 *
 *  Returns 0.0 on error.
 */


/*!
 * Return the center of the element 'elem' in (cx, cy).
 *
 *  \param h - Previously read header.
 *  \param elem - Element number from 0 to compute the center.
 *  \param *cx - Returns x.
 *  \param *cy - Returns y.
 *
 *  Returns ELIO_OK on success.
 *  Returns ELIO_ERR on failure.
 */


/*!
 * Return the center of the element 'elem' in (cx, cy).
 *
 *  \param g - Previously read grid.
 *  \param elem - Element number from 0 to compute the center.
 *  \param *cx - Returns x.
 *  \param *cy - Returns y.
 *
 *  Returns ELIO_OK on success.
 *  Returns ELIO_ERR on failure.
 */


/*!
 * Return the area for the given element. Element numbering starts from 0.
 *
 *  Returns 0.0 on error.
 */


/*!
 * Read a grid
 *
 *  \param gname - Grid file name
 *  \param g - Pointer to a grid structure
 *
 *  Returns ELIO_OK on success.
 *  Returns ELIO_ERR on failure.
 */


/*!
 * Free a grid
 *
 *  \param g - Pointer to a grid structure with already allocated memory
 *
 *  Returns ELIO_OK on success.
 *
 *  No checking is done on validity of the pointers being freed
 */


/*!
 * Turn on CORIE time, should be called just once in any program.
 * Multiple calls will foul things up, so don't do it.
 */


/*!
 * Set corietime from a string. 4 digits for year.
 */


/*!
 * Return corieday relative to now. The variable 'when' can be +-.
 */


/*!
 *  Return the CORIE day or UNIX day + hms as a real number.
 */


/*!
 *  Convert a CORIE or UNIX day number to m-d-y hhmmss.
 */


/*!
 *  Convert a day number to y-yearday hhmmss.
 */


/*!
 * Inverse bilinear mapping for quadrangles from Joseph.
 * Convexity of the quad must have been checked, and (x,y) must
 * be inside the quad.
 *
 */


/*!
 *  Compute the depth at a given node and level for a sigma grid.
 *
 * Input variables:
 *
 * \param node = Node number starting from 0
 * \param level = Level number starting from 0
 * \param eh = Pointer to populated ElcircHeader struct
 *
 * Returns depth.
 *
 * Fortran code from ELCIRC
 *
 * do k=1,nvrt
 *     z(i,k)=peta(i)*(1+sigma(k))+h_c*sigma(k)+(dp(i)-h_c)*cs(k)
 * !           Abnormal cases
 *     if(ivcor==2.and.(dp(i)<=h_c.or.peta(i)<=-h_c-(dp(i)-h_c)*theta_f/dsinh(theta_f))) then
 *        iback(i)=0
 *        z(i,k)=peta(i)*(1+sigma(k))+dp(i)*sigma(k)
 *     endif
 *     if(k>=2.and.z(i,k)-z(i,k-1)<=0) then
 *        write(11,*)'Inverted z-levels at:',i,k,z(i,k)-z(i,k-1),peta(i),dp(i)
 *        stop
 *     endif
 * enddo !k
 *
 */


/*!
 *  Compute the depth at a given XY location and level for a sigma grid.
 *
 * Input variables:
 *
 * \param x = X co-ordinate of location
 * \param y = Y co-ordinate of location
 * \param level = Level number starting from 0
 * \param eh = Pointer to populated ElcircHeader struct
 *
 * Returns depth.
 *
 */


/*!
 *  Compute the depth at a given XYZ location for a sigma grid.
 *
 * Input variables:
 *
 * \param x = X co-ordinate of location
 * \param y = Y co-ordinate of location
 * \param z = z co-ordinate of location
 * \param eh = Pointer to populated ElcircHeader struct
 *
 * Returns depth.
 *
 */


/*!
 *  Return the min/max value in an array of doubles, utility function.
 *
 * Input variables:
 *
 * \param n = Number of doubles.
 * \param ar = Pointer to the doubles - assumed to be a valid pointer.
 *
 * Returns minimum double found in the array.
 *
 */


/*!
 *  Return the minimum value in an array of ints, utility function.
 *
 * Input variables:
 *
 * \param n = Number of integers.
 * \param iar = Pointer to the integers - assumed to be a valid pointer.
 *
 * Returns minimum integer found in the array.
 *
 */


/*!
 *  Return the maximum value in an array of ints, utility function.
 *
 * Input variables:
 *
 * \param n = Number of integers.
 * \param iar = Pointer to the integers - assumed to be a valid pointer.
 *
 * Returns maximum integer found in the array.
 *
 */


/*!
 *  Return the numeric file version number 2, 3, 4
 *
 * Input variables:
 *
 * \param fname = File name.
 *
 */


/*!
 *  Find the interval in an array containing the double d, return -1
 *  if no interval found. Data point is located in between index returned
 *  and index + 1.
 *
 * Input variables:
 *
 * \param n = Number of items in *data.
 * \param data = Array to search.
 * \param d = Item to locate.
 *
 * Returns 0 based index found or -1 if less than or n if greater than.
 *
 */


/*!
 * Given an array of depths and scalar quatities, interpolate
 * the scalar values to all the points in *zp. Clamp to values at
 * either end if point to find is out of range. Output to *sp.
 *
 * Input variables:
 *
 * \param n = Number of items in *z.
 * \param z = Depths.
 * \param s = Scalar value.
 * \param np = number of points to interpolate.
 * \param zp = Depths to interpolate to.
 * \param sp = Interpolated scalar values.
 */


/*!
 * Given an array of depths and scalar quantities, interpolate
 * a scalar value given the depth. Clamp to value at
 * either end if point to find is out of range. returns the
 * interplated value.
 *
 * Input variables:
 *
 * \param n = Number of items in *z.
 * \param z = Depths.
 * \param s = Scalar value.
 * \param zp = Depth to interpolate to.
 */


/*!
 * Given an array of depths and scalar quantities, interpolate
 * a scalar value given the index as found from ElioFindIndex().
 * Clamp to value at either end if point to find is out of range.
 *
 * Input variables:
 *
 * \param n = Number of items in *z.
 * \param z = Depths.
 * \param s = Scalar value.
 * \param ind = Index value.
 * \param zp = Depth to use for interpolation.
 */


/*!
 * Replace the nodes in the grid h with the nodes found in grid g.
 *
 * Useful for transforming a run done in one projection to another.
 *
 */


/*!
 * Get the grid from a header and stuff it in an ElioGrid struture
 *
 */


/* create format string */


/*
 * Create the comp Widget
 */


/* load a set */


/* sample a set */


/* apply a digital filter in set 2 to set 1 */


/* evaluate a formula - load the next set */


/*
 * evaluate a formula
 */


/*
 * load a set
 */


/*
 * evaluate a formula loading the next set
 */


/*
 * apply a digital filter
 */


/*
 * running averages, medians, min, max, std. deviation
 */


/*
 * DFT by FFT
 */


/*
 * Apply data window only
 */


/*
 * sample a set, by start/step or logical expression
 */


/*
 * Create the whist Frame and the whist Panel
 */


/*
 * drawpolymissing - draw a connected line in the current color and linestyle
 *            with nodes given by (x[],y[])
 */


/*
 * drawpolarpoly - draw a connected line in the current color and linestyle
 *            with nodes given by (x[] = r,y[] = theta) in polar coordinates
 */


/*
 * draw a circle symbol
 */


/*
 * draw an arrow
 * end = 0 = none 1 = arrow at x1, y1  2 = arrow at
 * x2, y2 3 arrow at both ends
 */


/*
 * Draw the legend for velocities
 */


/*
 * draw the direction legend
 */


/*
 * draw the percent legend
 */


/*
 * draw the legend for barcharts at world coordinates (x,y)
 */


/*
 * Create the editor using xterm & GR_EDITOR
 */


/*
 * initialize the X-Toolkit
 */


/*
 * stuff results, etc. into a text window
 */


/*
   void HelpCB(Widget w, XtPointer client_data, XtPointer call_data);
 */


/*
 * service the autoscale buttons on the main panel
 */


/*
 * service the auticks button on the main panel
 */


/*
 * clear the locator reference point
 */


/*
 * initialize pixmaps for buttons on front
 */


/* scrunch a pair of integer arrays */


/* scrunch the array of XPoints */


/* NOTE: not called by xvgr */


/*
 * save_image_on_disk - this routine saves the region specified by the various
 *               parameters out to disk in the "defacto standard" (xwd) format.
 *               This has now been modified to take two window id's.  The
 *               first is to gather "window" information such as visual
 *               type, etc, and the second is where the image comes from.
 *               This is because in wscrawl 2.0, the image comes from a
 *               Pixmap, so pixmaps are VALID for the second win_id, but
 *               not for the first.  In the simple case of getting an
 *               image from a window, just pass the window id in twice.
 *
 *               "the_colormap" can be NULL if you wish to use the default
 *               colormap.  Most times this will be the case.
 */


/*
 * Get_Colors - takes a pointer to an XColor struct and returns the total
 *            number of cells in the current colormap, plus all of their
 *            RGB values.
 */


/*
 * allocate_colors_and_assign_em - this function takes an XImage and it's
 *            colormap as it was at the time the image was created, and
 *            allocates cells in the system colormap matching those old colors
 *            and shuffles the pixels in the image to point to our new color
 *            cells instead of those old color cells.
 */


/*
 * Notify and event procs
 */


/*
 * evaluate the expression in sscanstr and place the result in selset
 */


/*
 * Create the ticks popup
 */


/*
 * define tick marks
 */


/*
 * draw all active graphs, when graphs are drawn, draw the focus markers
 */


/*
 * force a redraw when auto-redraw is OFF
 */


/*
 * repaint proc for Motif
 */


/*
 * draw the graph focus indicators
 */


/*
 * define a region
 */


/*
 * draw a crosshair cursor
 */


/*
 * pan through world coordinates
 */


/*
 * world stack operations
 */


/*
 * the following function is for debug purposes, testing for in/out
 */


/*
 * allocate arrays for a set of length len.
 */


/*
 * compute the mins/maxes and update the appropriate fields of
 * set i.
 */


/*
 * moveset assumes both sets exist, have their length
 * properly set, and that they are both active
 */


/*
 * copyset assumes both sets exist, have their length
 * properly set, and that they are both active
 */


/*
 * copy everything but the data
 */


/*
 * copy data only
 */


/*
 * pack all sets leaving no gaps in the set structure
 */


/*
 * return the next available set in graph gno
 * ignoring deactivated sets.
 */


/*
 * kill a set
 */


/*
 * kill a set, but preserve the parameter settings
 */


/*
 * activate a set
 */


/*
 * return the active status of a set
 */


/*
 * drop points from a set
 */


/*
 * join 2 sets together
 */


/*
 * for ascending and descending sorts
 */


/*
 * sort a set - only does type XY
 */


/*
 * locate a point and the set the point is in
 */


/*
 * locate a point in setno nearest (x, y)
 */


/*
 * delete the point pt in setno
 */


/*
 * add a point to setno
 */


/*
 * add a point to setno after or before ind
 */


/*
 * add points to setno
 */


/*
 * copy a set to another set, if the to set doesn't exist
 * get a new one, if it does, ask if it is okay to overwrite
 */


/*
 * move a set to another set, in possibly another graph
 */


/*
 * swap a set with another set
 */


/*
 * activate a set and set its length
 */


/*
 * split a set into lpart length sets
 */


/*
 * break a set at a point
 */


/*
 * write out a set
 */


/*
 * de-activate a set
 */


/*
 * re-activate a set
 */


/*
 * change the type of a set
 */


/*
 * set the length of an active set - contents are destroyed
 */


/*
 * move a set to another set, if the to set doesn't exist
 * get a new one, if it does, ask if it is okay to overwrite
 */


/*
 * drop points from an active set
 */


/*
 * append one set to another
 */


/*
 * reverse the order of a set
 */


/*
 * kill all active sets
 */


/*
 * sort sets, only works on sets of type XY
 */


/*
 * write out all sets in binary
 */


/*
 * read file type 0
 */


/*
 * read the first set found in a file to set setno
 */


/*
 * read IHL format
 */


/*
 * read BP format
 */


/*
 * read file types using dx and/or dy
 */


/*
 * read block data
 */


/*
 * read a variable from netcdf file into a set in graph gno
 * xvar and yvar are the names for x, y in the netcdf file resp.
 * return 0 on fail, return 1 if success.
 *
 * if xvar == NULL, then load the index of the point to x
 *
 */


/*
 * read a 2d variable from netcdf file with each column going to
 * a different set.
 */


/*
 * write out sets in netcdf format
 */


/*
 * get a line from a file ended by a newline character
 */


/*
 *  write a set or sets to a file
 */


/*
 * split sets split by itmp, remainder in last set.
 */


/*           mif initialization routine  */


/*
 * accept this file/command setting
 */


/*
 * Create the draw Frame and the draw Panel
 */


/*
	simple gauss elimination - no pivoting or scaling strategies
	all matrices are sym-pos-def
*/


/*
	compute mean and standard dev
*/


/*
	least squares polynomial fit - for polynomials
	of degree 5 or less
*/


/*
	evaluate least squares polynomial
*/


/*
	compute a running average
*/


/*
	compute a running standard deviation
*/


/*
	compute a running median
*/


/*
	compute a running minimum or maximum
*/


/*
	Apply a digital filter of length len to a set in x, y,
	of length n with the results going to resx, resy.
	the length of the result is set by the caller
*/


/*
	linear convolution of set x (length n) with h (length m) and
	result to y. the length of y is set by the caller
*/


/*
 *	References,
 *
 *	_Applied Linear Regression_, Weisberg
 *	_Elements of Statistical Computing_, Thisted
 *
 * 	Fits y = coef*x + intercept + e
 *
 * 	uses a 2 pass method for means and variances
 *
 */


/*
	a literal translation of the spline routine in
	Forsyth, Malcolm, and Moler
*/


/*

#define STUFF_TEXT 0
#define STUFF_START 1
#define STUFF_STOP 2

 * sp = 0, just put text
 * sp = 1, place text at end initialize savepos (for sp = 2)
 * sp = 2, place text at end and go to the beginning of the sequence
 */


/*
 * define the velocity scale for this graph and properties of the
 * velocity scale legend
 */


/*
 * place the velocity scale
 */


/*
 * update the velocity scale popup
 */


/*
 * accept the current state of the velocity popup
 */


/*
 * Create the frame Widget and the frame Widget
 */


/* possibly defunct as reversal of axes depends on xv1 > xv2 */


/*
 * draw the legend at (legx, legy)
 * ib = 1 in loop means accumulate info for box
 * ib = -1 after loop means draw box
 */


/*
 * draw the graph frame
 */


/*
 * draw a set with a fill
 */


/*
 * draw a standard set with symbols and lines
 */


/*
 * draw a value as a string at x, y
 */


/*
 * draw a density plot
 */


/*
 *  Draw the isolines
 */


/*
 * draw a specified symbol at a point with color and size
 */


/*
 * draw a circle centered at x, y with radius z
 */


/*
 * draw a set in a bar chart
 */


/*
 * draw a set in a horizontal bar chart
 */


/*
 * draw a set in a stacked bar chart
 */


/*
 * draw a set in a horizontal stacked bar chart
 */


/*
 * draw a set with error bars
 */


/*
 * draw each point in a set as a boxplot
 *
 * e[1] is the median,
 * e[2] is the lower inner value
 * e[3] is the upper inner value
 * e[4] is the lower whisker
 * e[5] is the upper whisker
 */


/*
 * draw a standard set with symbols and lines in a polar plot
 */


/*
 * Create the label Frame and the label Panel
 */


/*
 * extract sets from graph gfrom to graph gto
 * a set is in a region if any point of the set is in the region
 */


/*
 * delete sets from graph gno
 * a set is in a region if any point of the set is in the region
 */


/*
 * routines to determine if a point lies to the left of an infinite line
*/


/*
 * routines to determine if a point lies above an infinite line
*/


/*
 * routines to determine if a point lies below an infinite line
*/


/*
 * Monitor a growing netcdf file
 */


/*
 * Event and Notify proc declarations
 */


/*
 * define the draw options
 */


/*
 * activate the add point item in the canvas event proc
 */


/*
 * activate the find point item in the canvas event proc
 */


/*
 * activate the delete point item in the canvas event proc
 */


/*
 * move a point
 */


/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
   quotes and backslashes, so that it's suitable for yyerror.  The
   heuristic is that double-quoting is unnecessary unless the string
   contains an apostrophe, a comma, or backslash (other than
   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
   null, do not copy; instead, return the length of what the result
   would have been.  */


/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
   about the unexpected token YYTOKEN for the state stack whose top is
   YYSSP.

   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
   not large enough to hold the message.  In that case, also set
   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
   required number of bytes is too large to store.  */


/*
 * Create the files Frame and the files Panel
 */


/* this may no longer be needed
#ifndef HAS_TOLOWER
int tolower(int c)
{
    if (c >= 'A' && c <= 'Z') {
	return (c - ' ');
    } else {
	return c;
    }
}
#endif
*/


/*
 * write the status to the results file
 */


/*
 * define symbols for the current set
 */


/*
 * freshen up symbol items, generally after a parameter
 * file has been read
 */


/*
 * freshen up legend items, generally after a parameter
 * file has been read
 */


/*
 * create the symbols popup
 */


/*
 * define legends for the current graph
 */


/*
 * activate the legend location flag
 */


/*
 * load legend strings from set comments
 */


/*
 * create the legend popup
 */


/*
 * define errbars for the current set
 */


/*
 * create the errbar popup
 */


/*
 * define boxplot for the current set
 */


/*
 * create the boxplot popup
 */


/*
	DFT by definition
*/


/*
* Bit swaping routine in which the bit pattern of the integer i is reordered.
* See Brigham's book for details
*/


/*
* Simple exchange routine where *x1 & *x2 are swapped
*/


/*
 * forward, backward and centered differences
 */


/*
 * difference a set
 * itype means
 *  0 - forward
 *  1 - backward
 *  2 - centered difference
 */


/*
 * seasonally difference a set
 */


/*
 * regression with restrictions to region rno if rno >= 0
 */


/*
 * DFT by FFT or definition
 */


/*
 * Apply a window to a set, result goes to a new set.
 */


/*
 * cfree and check for NULL pointer
 */


/*
 * convert a string from lower to upper case
 * leaving quoted strings alone
 */


/*
 *  * return the Julian day + hms as a real number
 *
*/


/*
 * Given the graph gno, find the graph that contains
 * (wx, wy). Used for setting the graph focus.
 */


/*
	 the following routines determine default scaling and tickmarks
*/


/*
 * for zooms, lz => linked to all active graphs
 *
 */


/*
 *   * strip special chars from a string
 *    */


/*
 * scale coordinates, using a SVG-viewer to do this gives rounding-problems
 */


/*
 * escape special characters
 */


/*
 * drawtic - interface to device driver routines, done this way
 *           as there were problems with low resolution devices
 *           (this is probably not necessary now)
 *      dir = 0 = draw in up (for x-axis) or right (for y-axis)
 *      axis = 0 = draw x-axis tic,   1 = y-axis
 */


/*
 * writestrbox - user interface to the current device text drawing routine
 */


/*
 * generate plots in batch mode, sequence of gifs
 */


/*
 * XtFlush - Flushes all Xt events.
*/


/*
 * generic unmanage popup routine, used elsewhere
 */


/*
 * Get a file name from a file browser
 */


/*
 * Open a file browser
 */


/*
 * Time histories of flow
*/


/*
 * find out about data at a node at this time step
 *
 */


/*
 * Create the slice Frame and the slice Panel
 */


/*-----------------------------------.
| Print this symbol's value on YYO.  |
`-----------------------------------*/


/*---------------------------.
| Print this symbol on YYO.  |
`---------------------------*/


/*------------------------------------------------------------------.
| yy_stack_print -- Print the state stack from its BOTTOM up to its |
| TOP (included).                                                   |
`------------------------------------------------------------------*/


/*------------------------------------------------.
| Report that the YYRULE is going to be reduced.  |
`------------------------------------------------*/


/*-----------------------------------------------.
| Release the memory associated to this symbol.  |
`-----------------------------------------------*/


/*
 * find out about data at a node at this time step
 */


/*
 * find out about maximum elevations at a node
 */


/*
 * set isolines of elevations and isolines of maximum elevations
 */


/*
 * create the popup used to set properties for the display of ADCIRC flows
 */


/*
 * freshen up the ADCIRC setup panel
 */


/*
 * Accept the current state of the ADCIRC popup
 */


/*
 * place the currently selected elevation marker
 */


/*
 * edit an elevation marker
 */


/*
    int display_inun;
    int display_irestrict;
    Props wet, dry, wetdry;
*/


/*
 * Scalar data set up frame
 */


/*
 * Vector data set up frame
 */


/*
 * eval r, s in a 4 node quadrangle
 */


/*
 * eval r, s in an 8 node quadrangle
 */


/*
 * Write type Props version 0
 */


/* write isoline settings */


/* draw color filled elements with courant number of the courant number
 * values themselves
 */


/*
 * Sample velocities to cut down the clutter
 */


/*
 * Read a frequency domain flow file
 */


/*
 * filet = 0 - both elevations and flows
 * filet = 1 - elevations
 * filet = 2 - flows
 */


/*
 * read fort.63 file
 */


/*
 * flowno: this flow
 * gridno: the domain to use
 * fname: the file name
 * keep: boolean to determine if this is a standalone file or connected
 *       to a fort.63 file - keep == 1 => yes, both fort.63 and fort.64 files
 *       are to be read to this flow.
 */


/*
 * Read values at a given depth, interpolating for each node, for sigma grids.
 *
 * fname is data files, zname is zcor file.
 *
 */


/*
 * Read values at a given depth below the free surface, interpolating for each node, for sigma grids.
 *
 * fname is data files, zname is zcor file.
 *
 */


/*
 * interpolate between 2 time steps
 */


/*
** Takes a date, and returns a Julian day. A Julian day is the number of
** days since some base date  (in the very distant past).
** Handy for getting date of x number of days after a given Julian date
** (use jdate to get that from the Gregorian date).
** Author: Robert G. Tantzen, translator: Nat Howard
** Translated from the algol original in Collected Algorithms of CACM
** (This and jdate are algorithm 199).
*/


/* Julian date converter. Takes a julian date (the number of days since
** some distant epoch or other), and returns an int pointer to static space.
** ip[0] = month;
** ip[1] = day of month;
** ip[2] = year (actual year, like 1977, not 77 unless it was  77 a.d.);
** ip[3] = day of week (0->Sunday to 6->Saturday)
** These are Gregorian.
** Copied from Algorithm 199 in Collected algorithms of the CACM
** Author: Robert G. Tantzen, Translator: Nat Howard
*/


/*
 * print the data part of a plot string
 * for debugging.
 */


/*
 * set action to SEL_POINT for selecting the locator reference point
 */


/* read params popup */


/*
	compute the isolines
*/


/*
static void autoscale_type_proc(w, cd)
    Widget w;
    int cd;
{
    if (cd == 0) {
	g[cg].auto_type = AUTO;
    } else {
	g[cg].auto_type = SPEC;
    }
}

static void autoscale_set_proc()
{
    int value;
    value = (int) GetChoice(autoscale_set_item);
    if (isactive(cg, value)) {
	defaultsetgraph(cg, value);
	default_axis(cg, g[cg].auto_type, X_AXIS);
	default_axis(cg, g[cg].auto_type, ZX_AXIS);
	default_axis(cg, g[cg].auto_type, Y_AXIS);
	default_axis(cg, g[cg].auto_type, ZY_AXIS);
	update_world(cg);
	drawgraph();
    } else {
	errwin("Set not active!");
    }
}
*/


/*
 * return the string equiv of the scaling parameter
 */


/*
 * place the time line
 */


/*
 * place the tidal clock
 */


/*
 * popup for time line properties
 */


/*
 * update the time line popup
 */


/*
 * register the current state of the time line popup
 */


/*
 * create a property sheet for the tidal clock
 */


/*
 * make the state of the tidal clock current
 */


/*
 * popup to set the map scale legend
 */


/*
 * place the map scale legend for the current graph
 */


/*
 * update the map scale popup
 */


/*
 * accept the current settings
 */


/*
 * create the flux scale popup
 */


/*
 * set the posistion of the flux scale for this graph
 */


/*
 * update the flux scale popup
 */


/*
 * accept the current state of the flux scale popup
 */


/*
 * place the timeinfo string
 */


/*
 * Display the timeinfo string and set properties
 */


/*
 * evaluate elevations from tide station at time t
 * using constituent. If constituent == -1, then use all available
 * frequncies
 */


/*
 * evaluate velocities from tide station at time t
 * using constituent. If constituent == -1, then use all available
 * frequencies, return magnitude
 */


/*
 * do a single plot then quit
 */


/*
 *  int writeflag;
 *  char wname[256];
 *  int writelevel[MAXISOLINES];
*/


/* helper function to invert the order of the array so top is 0 and bottom is n */


/**
  @brief    Set the group as RAW or CALIB in a frameset
  @param    set     the input frameset
  @return   CPL_ERROR_NONE iff OK
 */


/**
  @brief    find out the DIT value
  @param    plist       property list to read from
  @return   the requested value
 */


/**
  @brief    Build the list of available plugins, for this module.
  @param    list    the plugin list
  @return   0 if everything is ok, 1 otherwise
  @note     Only this function is exported

  Create the recipe instance and make it available to the application using the
  interface.
 */


/**
  @brief    Interpret the command line options and execute the data processing
  @param    frameset   the frames list
  @param    parlist    the parameters list
  @return   0 if everything is ok
 */


/* This module provides all needed functions to run a recipe from the
   framework. These functions are extracted from the recipe shared lib
   (resp. the CPL linked to that) by their names. I checked that the API
   didn't change from CPL 4.0 which is now the minimal supported version here.

   Since some constants changed over the time, all used constants are
   also included in the structure. The constants are set directly depending on
   the CPL version number.

   Note that beta releases have to be taken very cautiously here since they
   may contain incompatible changes here.
*/


//  gspsphere: construct realization from GSP data.
//  _______________________________________________


//  gsp_plum: initialize tables for Plummer model.
//  ______________________________________________


//  readgsp: read sphr GSP from input.
//  __________________________________


//  writemodel: write N-body model to output.
//  _________________________________________


//  dgdisk: integrand for radial acceleration with smoothing. Note: potential
//  at z = 0 with smoothing equals potential at z = epsilon without smoothing.
//  __________________________________________________________________________


//  listdisk: print table listing disk parameters.
//  ______________________________________________


//  makedisk: create realization of disk.
//  _____________________________________


//  padlist: pad string list to specified length.
//  _____________________________________________


/*
 * GSPMODEL: construct realization from GSP data.
 */


//  gsp_phi: evaluate potential at given radius.
//  ____________________________________________


//  gsp_phi_rad: evaluate radius corresponding to given potential.
//  ______________________________________________________________


//  gsp_calc_phi: calculate gravitational potential of the given profile.
//  _____________________________________________________________________


//  gsp_gamma: initialize tables for gamma model.
//  _____________________________________________


//  gsp_realize: construct realization from distribution function.
//  ______________________________________________________________


//  init_hmax: initalize the table used to find hmax(phi).
//  ______________________________________________________


//  pick_speed: chose speed distributed according to h(v).
//  ______________________________________________________


//  hfunc: compute speed distribution (up to a factor of 4 PI).
//  ___________________________________________________________


//  berank: rank bodies by binding energy.
//  ______________________________________


//  gsp_expd: initialize tables for "spherical exponential disk".
//  _____________________________________________________________


/*
 * POLYGSP: initialize tables for polytropic spheres.
 */


//  gsp_add: add two density profiles and replace first with sum.
//  _____________________________________________________________


//  gsp_sig2: evaluate square of velocity dispersion at given radius.
//  _________________________________________________________________


//  gsp_calc_sig2: calculate radial dispersion needed to support the
//  density profile dgsp in the potential of profile ggsp.
//  ________________________________________________________________


/*
 * ISOTHGSP: non-singular truncated isothermal.
 */


//  readgsp: read spheroid gsp from input file.
//  ___________________________________________


//  writemodel: write N-body model to output file.
//  ______________________________________________


/*
 * GSPTRUN: impose exponential cutoff at radius rtrun0.
 */


/*
 * FIXMASS: rescale model to total mass mtot0.
 */


//  gsp_halo_e: initialize Navarro et al model with exponential taper.
//  __________________________________________________________________


//  gsp_halo_g: initialize Navarro et al model with gaussian taper.
//  _______________________________________________________________


//  gsp_halo_sw: initialize Navarro et al model with fast taper
//  (Springel & White 1998, astro-ph/9807320).
//  ___________________________________________________________


//  gsp_dist: evaluate distribution function f = f(E) = dF/dE.
//  __________________________________________________________


//  gsp_dist_integ: evaluate integral of distribution function F(E).
//  ________________________________________________________________


//  gsp_calc_dist: calculate tables for distribution function.
//  __________________________________________________________


//  gsp_calc_dist_pars: set parameters for numerical integration.
//  _____________________________________________________________


//  f_hernquist: compute DF for Hernquist model.
//  ____________________________________________


//  f_plummer: compute DF for Plummer model.
//  ________________________________________


//  gsp_rho: evaluate density at given radius.
//  __________________________________________


//  gsp_grad: evaluate radial derivative of density at given radius.
//  ________________________________________________________________


//  gsp_mass: evaluate enclosed mass at given radius.
//  _________________________________________________


//  gsp_mass_rad: evaluate radius enclosing given mass.
//  ___________________________________________________


//  gsp_read: read profile tables from input stream.
//  ________________________________________________


//  gsp_write: write profile tables to output stream.
//  _________________________________________________


//  gsp_free: deallocate a gsp and associated tables.
//  _________________________________________________


/*
 * FINDOBJ: identify objects by percolation.
 */


/*
 * LINKPART: put particles in same equiv. class.
 */


/*
 * TOPLINK: follow link chain to self-referent particle.
 */


//  execmap: start snapmap subprocess, and return snapmap output stream.
//  ____________________________________________________________________


//  plummodel: generate N-body realization of Plummer model, scaled
//  to units such that G = M = -4E = 1 (Henon, Hegge, etc).
//  See Aarseth, SJ, Henon, M, & Wielen, R (1974) Astr & Ap, 37, 183.
//  _________________________________________________________________


//  berank: compare binding energies of particles, for sorting.
//  ___________________________________________________________


//  polysolve: solve structure equation for generalized polytrope.
//  ______________________________________________________________


//  asmpstep: asymptotic approx. for generalized polytrope near r=0.
//  ________________________________________________________________


//  diffrpmw: differentials of radius, potential, mass, binding energy.
//  ___________________________________________________________________


//  storestep: tabulate results of integration.
//  ___________________________________________


//  fixsurface: locate radius of surface by linear interpolation.
//  _____________________________________________________________


//  polyscale: scale model to Henon's units.
//  ________________________________________


//  polymodel: construct N-body realization of polytrope.
//  _____________________________________________________


//  rad_m: compute radius as a function of enclosed mass.  Cannot use
//  a spline since mass increments can become very small near r_1.
//  __________________________________________________________________


//  pick_psi: pick angle between velocity and radial vectors.
//  _________________________________________________________


//  pick_v: pick magnitude of velocity.
//  ___________________________________


//  polymodel2: generate polytrope model for n = 1/2, m = -1/2.
//  ___________________________________________________________


/*
 * INITEXTFIELD: read force-field tables.
 */


/*
 * EXTFORCE: find force and potential of axysymmetric field.
 */


/*
 * PHI, A_S, A_Z: compute potential, acceleration.
 */


/*
 * D_PHI, D_A_S, D_A_Z: integrands for potential, accelerations.
 */


/*
 * SIMPSON: integrate given function using Simpson's rule.
 */


/*
 * READSPHR: read spheroid model from input.
 */


/*
 * WRITEGAL: write galaxy model to output.
 */


/*
 * TESTDISK: use tabulated spheroid mass profile to make a uniform
 * density test disk.  Note that the softening correction is only
 * exact for a central point mass.
 */


//  layout_body: define real and vector types according to client,
//  and add named fields to body structure.
//  ______________________________________________________________


//  define_body: define real and vector types according to client,
//  and sets body length.
//  ______________________________________________________________


//  define_body_offset: fixed-offset interface sets field offset.
//  _____________________________________________________________


//  snapke: return total kinetic energy.
//  ____________________________________


//  snappe: return total potential energy.
//  ______________________________________


//  snapamvec: compute angular momentum vector.
//  ___________________________________________


//  snapketen: compute kinetic energy tensor.
//  _________________________________________


//  snappeten: compute potential energy tensor.
//  ___________________________________________


//  snapmiten: compute moment of inertia tensor.
//  ____________________________________________


//  snapcmpos: compute center of mass position.
//  ___________________________________________


//  snapcmvel: compute center of mass velocity.
//  ___________________________________________


//  snapcmacc: compute center of mass acceleration.
//  _______________________________________________


//  snapcenter: transform to the weighted center of mass.
//  _____________________________________________________


//  buildmap: generate extendbody, computemap, and computetime routines;
//  compile and link with snapmap main program.
//  ____________________________________________________________________


//  put_snap: write snapshot to structured output stream.
//  _____________________________________________________


//  maketree: initialize tree structure for hierarchical force calculation.
//  _______________________________________________________________________


//  inputgrav: read GSP for external grav field, if defined.
//  ________________________________________________________


//  startoutput: begin output to log file and stream file.
//  __________________________________________________


//  outputhead: announce beginning of new time-step.
//  ________________________________________________


//  outputdata: output diagnostics and binary data.
//  _______________________________________________


//  savestate: write current state to disk file.
//  ____________________________________________


//  restorestate: restore state from disk file.
//  ___________________________________________


/*
 * INIT_SMOOTH: create smoothing context and initialize arrays.
 */


/*
 * FINISH_SMOOTH: clean up after smoothing operations.
 */


/*
 * SMOOTH: construct neighbor lists and invoke smoothing function.
 */


/*
 * RESMOOTH: reconstruct neighbor lists and invoke smoothing function.
 */


/*
 * REPORT_SMOOTH: output report on smoothing operations.
 */


//  gravforce: perform force calculation on all particles.
//  ______________________________________________________


//  report_force: print statistics on tree construction and force calculation.
//  __________________________________________________________________________


/*
 * SNAP_PIX: render image to rpix, gpix, bpix arrays.
 */


/*
 * COLOR_HIST: construct histogram of body colors.
 */


/*
 * CLEAR_RGB: zero out rpix, gpix, bpix arrays.
 */


/*
 * ADD_RGB: transfer current image to rpix, gpix, bpix arrays.
 */


/*
 * LOAD_GRID: interpolate bodies onto pixel-grid.
 */


/*
 * SMOOTH_GRID: smooth grid using iterated boxcar.
 */


//  smooth_rho: interpolate density onto sample grid.
//  _________________________________________________


//  smooth_aux: interpolate aux onto sample grid.
//  _____________________________________________


//  smooth_bright: interpolate brightness onto sample grid.
//  _______________________________________________________


//  put_ppm: output pixel data in linear ppm format.
//  ________________________________________________


// pixmap: transform real grid value to integer pixel value.
// _________________________________________________________


// pixclip: limit pixel value to allowed range, and count exceptions.
// __________________________________________________________________


//  execmap: use compiled program to map input snap to output snap.
//  _______________________________________________________________


//  snaprotate: perform rotation about specified axes.
//  __________________________________________________


//  rotate: perform rotation about one axis.
//  ________________________________________


/*
 * OUTPUT: write out snapshot file.
 */


/*
 * RESTORESTATE: restore state from disk file.
 */


//  inputdata: read initial conditions from input file.
//  ___________________________________________________


//  startoutput: begin output to log file.
//  ______________________________________


//  forcereport: print staristics on tree construction and force calculation.
//  _________________________________________________________________________


//  output: compute diagnostics and output binary data.
//  ___________________________________________________


//  savestate: write current state to external file.
//  ________________________________________________


//  restorestate: restore state from external file.
//  _______________________________________________


//  gravcalc: perform force calculation on all particles.
//  _____________________________________________________


//  init_random: select and initialize random number generator.  For
//  backward compatibility, default reproduces unix random() function;
//  set GSL_RNG_TYPE environment variable to select better generators.
//  __________________________________________________________________


//  xrandom: floating-point random number in range [xl,xh], inclusive;
//  computed by scaling unsigned long, so at most 32 bits are random.
//  __________________________________________________________________


//  grandom: normally distributed random number (polar method).
//  Reference: Knuth, vol. 2, p. 104.
//  ___________________________________________________________


//  layout_struct: compute offsets and length of structure.  The order
//  of the active fields is determined by the names argument.  Padding
//  is computed assuming (1) any object can have offset 0, and
//  (2) identical objects can be stored contiguously without padding.
//  Lines with TEST comments prototype construction of structure type.
//  __________________________________________________________________


//  new_field: define a new field of given type and name.
//  _____________________________________________________


//  define_struct: set total length of structure.
//  Partial alternative to layout_struct for fixed-offset interface.
//  ________________________________________________________________


//  define_offset: set offset of pre-defined field.
//  Partial alternative to layout_struct for fixed-offset interface.
//  ________________________________________________________________


//  stropen: open a stdio stream like fopen(), with these extensions:
//  1.  error checking: stropen() can only return NULL if mode == "r?";
//  2.  data protection: files can only be clobbered if mode == "w!";
//  3.  names of the form "-" map to stdin/stdout, depending on mode;
//  4.  names of the form "-num" open a stream to read/write f.d. num.
//  ___________________________________________________________________


//  within: determine if a floating point number is within specified
//  range list, passed in the form "<range>_1,<range>_2,..." where
//  each <range> is either one floating point number, two numbers
//  "<low>:<high>", or three numbers "<low>:<high>:<step>".  To allow
//  for small uncertainties in the values tested, floating-point
//  comparison is done with a specified fuzzyness parameter.  Now
//  accepts <range> of form
//  _________________________________________________________________


//  initparam: initalize parameter lists and handle special requests.
//  _________________________________________________________________


//  seval: evaluate cubic spline interpolation.
//  ___________________________________________


//  spldif: evaluate derivative of cubic spline.
//  ____________________________________________


//  skip_history: read past history items.
//  ______________________________________


//  put_history:  write current history and headline data to output.
//  ________________________________________________________________


//  add_history: add item to history array.
//  _______________________________________


//  bessel_J0: regular Bessel function J, order zero.
//  _________________________________________________


//  bessel_J1: regular Bessel function J, order one.
//  ________________________________________________


//  bessel_J: regular Bessel function J, order nu.
//  ______________________________________________


//  bessel_I0: regular modified cylindrical Bessel function I, order zero.
//  ______________________________________________________________________


//  bessel_I1: regular modified cylindrical Bessel function I, order one.
//  _____________________________________________________________________


//  bessel_I: regular modified cylindrical Bessel function I, order nu.
//  ___________________________________________________________________


//  bessel_K0: irregular modified cylindrical Bessel function K, order zero.
//  ________________________________________________________________________


//  bessel_K1: irregular modified cylindrical Bessel function K, order one.
//  _______________________________________________________________________


//  bessel_K: irregular modified cylindrical Bessel function K, order nu.
//  _____________________________________________________________________


//  error: scream and die quickly.
//  ______________________________


//  fatal: scream and die an ugly death.
//  ____________________________________


//  eprintf: print messages and warnings.  Uses "ZENO_MSG_OPTION" env. var.
//  to control printing; "warn" or "none" suppress some or all output.
//  _______________________________________________________________________


//  putxstr: write extended string to output stream, return TRUE on success.
//  ________________________________________________________________________


//  copxstr: make copy of extended string in allocated memory, return pointer.
//  __________________________________________________________________________


//  xstrlen: count number of values (including null) in extended string.
//  ____________________________________________________________________


//  xstreq: determine if extended strings are equal, return TRUE if so.
//  ___________________________________________________________________


//  pickshell: pick point on shell.
//  _______________________________


//  pickball: pick point within ball.
//  _________________________________


//  pickbox: pick point within box.
//  _______________________________


//  type_length: compute total size of basic or compound type.
//  __________________________________________________________


//  type_base: return basic type of homogenious compound type.
//  __________________________________________________________


//  copy_item: recursively copy item from input to output.
//  An example of recursive file traversal and memory etiquette.
//  ____________________________________________________________


//  put_set: begin named set in output stream.
//  __________________________________________


//  put_tes: end set in output stream.
//  __________________________________


//  put_string: write string to a structured file.
//  ______________________________________________


//  put_data: write data object to a structured file.
//  _________________________________________________


//  put_data_sub: routine to handle output operation, using arguments gathered
//  by put_data and put_data_masked, or supplied directly by the user.
//  __________________________________________________________________________


//  next_item_tag: return tag of next item in context,
//  or NULL at end of set or file.
//  __________________________________________________


//  skip_item: advance context within set, or flush item at toplevel.
//  Returns TRUE on success, FALSE on end of file.
//  _________________________________________________________________


// warn about data conversion


//  strclose: close stream and remove from stream state table.
//  __________________________________________________________


/*
 * READ_FILE: read file item by item, keeping track of sets.
 */


/*
 * READ_HEAD: input the type, tag, and dimensions of an item.
 */


/*
 * READ_DATA: input actual data of an item in ascii or binary.
 */


/*
 * READ_STRING: read a double-quote delimited string.
 */


/* actual indentation of line */


/*
 * SIFT_ITEM: decide if item should be copied to output.
 */


/*
 * COPY_ITEM_SIFTED: item/set copy, with sifting and other options.
 */


/*
 * SWAP_ORDER: reorder bytes within basic data elements.
 */


/*
** Return the number of LookasideSlot elements on the linked list
*/


/*
** Parse a timezone extension on the end of a date-time.
** The extension is of the form:
**
**        (+/-)HH:MM
**
** Or the "zulu" notation:
**
**        Z
**
** If the parse is successful, write the number of minutes
** of change in p->tz and return 0.  If a parser error occurs,
** return non-zero.
**
** A missing specifier is not considered an error.
*/


/*
** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
** The HH, MM, and SS must each be exactly 2 digits.  The
** fractional seconds FFFF can be one or more digits.
**
** Return 1 if there is a parsing error and 0 on success.
*/


/*
** Convert from YYYY-MM-DD HH:MM:SS to julian day.  We always assume
** that the YYYY-MM-DD is according to the Gregorian calendar.
**
** Reference:  Meeus page 61
*/


/*
** Parse dates of the form
**
**     YYYY-MM-DD HH:MM:SS.FFF
**     YYYY-MM-DD HH:MM:SS
**     YYYY-MM-DD HH:MM
**     YYYY-MM-DD
**
** Write the result into the DateTime structure and return 0
** on success and 1 if the input string is not a well-formed
** date.
*/


/*
** Attempt to parse the given string into a julian day number.  Return
** the number of errors.
**
** The following are acceptable forms for the input string:
**
**      YYYY-MM-DD HH:MM:SS.FFF  +/-HH:MM
**      DDDD.DD
**      now
**
** In the first form, the +/-HH:MM is always optional.  The fractional
** seconds extension (the ".FFF") is optional.  The seconds portion
** (":SS.FFF") is option.  The year and date can be omitted as long
** as there is a time string.  The time string can be omitted as long
** as there is a year and date.
*/


/*
** Compute the Year, Month, and Day from the julian day number.
*/


/*
** Compute the Hour, Minute, and Seconds from the julian day number.
*/


/*
** Clear the YMD and HMS and the TZ
*/


/*
** The following routine implements the rough equivalent of localtime_r()
** using whatever operating-system specific localtime facility that
** is available.  This routine returns 0 on success and
** non-zero on any kind of error.
**
** If the sqlite3GlobalConfig.bLocaltimeFault variable is non-zero then this
** routine will always fail.  If bLocaltimeFault is nonzero and
** sqlite3GlobalConfig.xAltLocaltime is not NULL, then xAltLocaltime() is
** invoked in place of the OS-defined localtime() function.
**
** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C
** library function localtime_r() is used to assist in the calculation of
** local time.
*/


/*
** Assuming the input DateTime is UTC, move it to its localtime equivalent.
*/


/*
** Process time function arguments.  argv[0] is a date-time stamp.
** argv[1] and following are modifiers.  Parse them all and write
** the resulting time into the DateTime structure p.  Return 0
** on success and 1 if there are any errors.
**
** If there are zero parameters (if even argv[0] is undefined)
** then assume a default value of "now" for argv[0].
*/


/*
**    julianday( TIMESTRING, MOD, MOD, ...)
**
** Return the julian day number of the date specified in the arguments
*/


/*
**    unixepoch( TIMESTRING, MOD, MOD, ...)
**
** Return the number of seconds (including fractional seconds) since
** the unix epoch of 1970-01-01 00:00:00 GMT.
*/


/*
**    datetime( TIMESTRING, MOD, MOD, ...)
**
** Return YYYY-MM-DD HH:MM:SS
*/


/*
**    time( TIMESTRING, MOD, MOD, ...)
**
** Return HH:MM:SS
*/


/*
**    date( TIMESTRING, MOD, MOD, ...)
**
** Return YYYY-MM-DD
*/


/*
**    strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
**
** Return a string described by FORMAT.  Conversions as follows:
**
**   %d  day of month
**   %f  ** fractional seconds  SS.SSS
**   %H  hour 00-24
**   %j  day of year 000-366
**   %J  ** julian day number
**   %m  month 01-12
**   %M  minute 00-59
**   %s  seconds since 1970-01-01
**   %S  seconds 00-59
**   %w  day of week 0-6  sunday==0
**   %W  week of year 00-53
**   %Y  year 0000-9999
**   %%  %
*/


/*
** current_time()
**
** This function returns the same value as time('now').
*/


/*
** current_date()
**
** This function returns the same value as date('now').
*/


/*
** current_timestamp()
**
** This function returns the same value as datetime('now').
*/


/*
** If the library is compiled to omit the full-scale date and time
** handling (to get a smaller binary), the following minimal version
** of the functions current_time(), current_date() and current_timestamp()
** are included instead. This is to support column declarations that
** include "DEFAULT CURRENT_TIME" etc.
**
** This function uses the C-library functions time(), gmtime()
** and strftime(). The format string to pass to strftime() is supplied
** as the user-data for the function.
*/


/*
** Unlink a VFS from the linked list
*/


/*
** Like malloc(), but remember the size of the allocation
** so that we can find it later using sqlite3MemSize().
**
** For this low-level routine, we are guaranteed that nByte>0 because
** cases of nByte<=0 will be intercepted and dealt with by higher level
** routines.
*/


/*
** Like free() but works for allocations obtained from sqlite3MemMalloc()
** or sqlite3MemRealloc().
**
** For this low-level routine, we already know that pPrior!=0 since
** cases where pPrior==0 will have been intecepted and dealt with
** by higher-level routines.
*/


/*
** Report the allocated size of a prior return from xMalloc()
** or xRealloc().
*/


/*
** Like realloc().  Resize an allocation previously obtained from
** sqlite3MemMalloc().
**
** For this low-level interface, we know that pPrior!=0.  Cases where
** pPrior==0 while have been intercepted by higher-level routine and
** redirected to xMalloc.  Similarly, we know that nByte>0 because
** cases where nByte<=0 will have been intercepted by higher-level
** routines and redirected to xFree.
*/


/*
** Initialize this module.
*/


/*
** Adjust memory usage statistics
*/


/*
** Given an allocation, find the MemBlockHdr for that allocation.
**
** This routine checks the guards at either end of the allocation and
** if they are incorrect it asserts.
*/


/*
** Return the number of bytes currently allocated at address p.
*/


/*
** Initialize the memory allocation subsystem.
*/


/*
** Fill a buffer with pseudo-random bytes.  This is used to preset
** the content of a new memory allocation to unpredictable values and
** to clear the content of a freed allocation to unpredictable values.
*/


/*
** Allocate nByte bytes of memory.
*/


/*
** Change the size of an existing memory allocation.
**
** For this debugging implementation, we *always* make a copy of the
** allocation into a new place in memory.  In this way, if the
** higher level code is using pointer to the old allocation, it is
** much more likely to break and we are much more liking to find
** the error.
*/


/*
** Unlink the chunk at mem3.aPool[i] from list it is currently
** on.  *pRoot is the list that i is a member of.
*/


/*
** Unlink the chunk at index i from
** whatever list is currently a member of.
*/


/*
** Link the chunk at mem3.aPool[i] so that is on the list rooted
** at *pRoot.
*/


/*
** Link the chunk at index i into either the appropriate
** small chunk list, or into the large chunk hash table.
*/


/*
** If the STATIC_MEM mutex is not already held, obtain it now. The mutex
** will already be held (obtained by code in malloc.c) if
** sqlite3GlobalConfig.bMemStat is true.
*/


/*
** Called when we are unable to satisfy an allocation of nBytes.
*/


/*
** Chunk i is a free chunk that has been unlinked.  Adjust its
** size parameters for check-out and return a pointer to the
** user portion of the chunk.
*/


/*
** Carve a piece off of the end of the mem3.iKeyBlk free chunk.
** Return a pointer to the new allocation.  Or, if the key chunk
** is not large enough, return 0.
*/


/*
** *pRoot is the head of a list of free chunks of the same size
** or same size hash.  In other words, *pRoot is an entry in either
** mem3.aiSmall[] or mem3.aiHash[].
**
** This routine examines all entries on the given list and tries
** to coalesce each entries with adjacent free chunks.
**
** If it sees a chunk that is larger than mem3.iKeyBlk, it replaces
** the current mem3.iKeyBlk with the new larger chunk.  In order for
** this mem3.iKeyBlk replacement to work, the key chunk must be
** linked into the hash tables.  That is not the normal state of
** affairs, of course.  The calling routine must link the key
** chunk before invoking this routine, then must unlink the (possibly
** changed) key chunk once this routine has finished.
*/


/*
** Return a block of memory of at least nBytes in size.
** Return NULL if unable.
**
** This function assumes that the necessary mutexes, if any, are
** already held by the caller. Hence "Unsafe".
*/


/*
** Free an outstanding memory allocation.
**
** This function assumes that the necessary mutexes, if any, are
** already held by the caller. Hence "Unsafe".
*/


/*
** Return the size of an outstanding allocation, in bytes.  The
** size returned omits the 8-byte header overhead.  This only
** works for chunks that are currently checked out.
*/


/*
** Round up a request size to the next valid allocation size.
*/


/*
** Allocate nBytes of memory.
*/


/*
** Change the size of an existing memory allocation
*/


/*
** Deinitialize this module.
*/


/*
** Unlink the chunk at mem5.aPool[i] from list it is currently
** on.  It should be found on mem5.aiFreelist[iLogsize].
*/


/*
** Link the chunk at mem5.aPool[i] so that is on the iLogsize
** free list.
*/


/*
** Return the size of an outstanding allocation, in bytes.
** This only works for chunks that are currently checked out.
*/


/*
** Return a block of memory of at least nBytes in size.
** Return NULL if unable.  Return NULL if nBytes==0.
**
** The caller guarantees that nByte is positive.
**
** The caller has obtained a mutex prior to invoking this
** routine so there is never any chance that two or more
** threads can be in this routine at the same time.
*/


/*
** Free an outstanding memory allocation.
*/


/*
** Free memory.
**
** The outer layer memory allocator prevents this routine from
** being called with pPrior==0.
*/


/*
** Change the size of an existing memory allocation.
**
** The outer layer memory allocator prevents this routine from
** being called with pPrior==0.
**
** nBytes is always a value obtained from a prior call to
** memsys5Round().  Hence nBytes is always a non-negative power
** of two.  If nBytes==0 that means that an oversize allocation
** (an allocation larger than 0x40000000) was requested and this
** routine should return 0 without freeing pPrior.
*/


/*
** Round up a request size to the next valid allocation size.  If
** the allocation is too large to be handled by this allocation system,
** return 0.
**
** All allocations must be a power of two and must be expressed by a
** 32-bit signed integer.  Hence the largest allocation is 0x40000000
** or 1073741824 bytes.
*/


/*
** Return the ceiling of the logarithm base 2 of iValue.
**
** Examples:   memsys5Log(1) -> 0
**             memsys5Log(2) -> 1
**             memsys5Log(4) -> 2
**             memsys5Log(5) -> 3
**             memsys5Log(8) -> 3
**             memsys5Log(9) -> 4
*/


/*
** Initialize the memory allocator.
**
** This routine is not threadsafe.  The caller must be holding a mutex
** to prevent multiple threads from entering at the same time.
*/


/*
** Allocate a mutex.
*/


/*
** Enter the mutex.
*/


/*
** The sqlite3_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it.  If it returns NULL
** that means that a mutex could not be allocated.
*/


/*
** This routine deallocates a previously allocated mutex.
*/


/*
** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
** to enter a mutex.  If another thread is already within the mutex,
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK
** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
** be entered multiple times by the same thread.  In such cases the,
** mutex must be exited an equal number of times before another thread
** can enter.  If the same thread tries to enter any other kind of mutex
** more than once, the behavior is undefined.
*/


/*
** The sqlite3_mutex_leave() routine exits a mutex that was
** previously entered by the same thread.  The behavior
** is undefined if the mutex is not currently entered or
** is not currently allocated.  SQLite will never do either.
*/


/*
** The sqlite3_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it.  If it returns NULL
** that means that a mutex could not be allocated.  SQLite
** will unwind its stack and return an error.  The argument
** to sqlite3_mutex_alloc() is one of these integer constants:
**
** <ul>
** <li>  SQLITE_MUTEX_FAST
** <li>  SQLITE_MUTEX_RECURSIVE
** <li>  SQLITE_MUTEX_STATIC_MAIN
** <li>  SQLITE_MUTEX_STATIC_MEM
** <li>  SQLITE_MUTEX_STATIC_OPEN
** <li>  SQLITE_MUTEX_STATIC_PRNG
** <li>  SQLITE_MUTEX_STATIC_LRU
** <li>  SQLITE_MUTEX_STATIC_PMEM
** <li>  SQLITE_MUTEX_STATIC_APP1
** <li>  SQLITE_MUTEX_STATIC_APP2
** <li>  SQLITE_MUTEX_STATIC_APP3
** <li>  SQLITE_MUTEX_STATIC_VFS1
** <li>  SQLITE_MUTEX_STATIC_VFS2
** <li>  SQLITE_MUTEX_STATIC_VFS3
** </ul>
**
** The first two constants cause sqlite3_mutex_alloc() to create
** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
** The mutex implementation does not need to make a distinction
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
** not want to.  But SQLite will only request a recursive mutex in
** cases where it really needs one.  If a faster non-recursive mutex
** implementation is available on the host platform, the mutex subsystem
** might return such a mutex in response to SQLITE_MUTEX_FAST.
**
** The other allowed parameters to sqlite3_mutex_alloc() each return
** a pointer to a static preexisting mutex.  Six static mutexes are
** used by the current version of SQLite.  Future versions of SQLite
** may add additional static mutexes.  Static mutexes are for internal
** use by SQLite only.  Applications that use SQLite mutexes should
** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
** SQLITE_MUTEX_RECURSIVE.
**
** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
** returns a different mutex on every call.  But for the static
** mutex types, the same mutex is returned on every call that has
** the same type number.
*/


/*
** This routine deallocates a previously
** allocated mutex.  SQLite is careful to deallocate every
** mutex that it allocates.
*/


/*
** Trigger the alarm
*/


/*
** Do a memory allocation with statistics and alarms.  Assume the
** lock is already held.
*/


/*
** "*val" is a double such that 0.1 <= *val < 10.0
** Return the ascii code for the leading digit of *val, then
** multiply "*val" by 10.0 to renormalize.
**
** Example:
**     input:     *val = 3.14159
**     output:    *val = 1.4159    function return = '3'
**
** The counter *cnt is incremented each time.  After counter exceeds
** 16 (the number of significant digits in a 64-bit float) '0' is
** always returned.
*/


/*
** Allocate memory for a temporary buffer needed for printf rendering.
**
** If the requested size of the temp buffer is larger than the size
** of the output buffer in pAccum, then cause an SQLITE_TOOBIG error.
** Do the size check before the memory allocation to prevent rogue
** SQL from requesting large allocations using the precision or width
** field of the printf() function.
*/


/*
** This is the routine that actually formats the sqlite3_log() message.
** We house it in a separate routine from sqlite3_log() to avoid using
** stack space on small-stack systems when logging is disabled.
**
** sqlite3_log() must render into a static buffer.  It cannot dynamically
** allocate memory because it might be called while the memory allocator
** mutex is held.
**
** sqlite3_str_vappendf() might ask for *temporary* memory allocations for
** certain format characters (%q) or for very large precisions or widths.
** Care must be taken that any sqlite3_log() calls that occur while the
** memory mutex is held do not use these mechanisms.
*/


/*
** Add a new subitem to the tree.  The moreToFollow flag indicates that this
** is not the last item in the tree.
*/


/*
** Finished with one layer of the tree
*/


/*
** Generate a single line of output for the tree, with a prefix that contains
** all the appropriate tree lines
*/


/* Thread procedure Win32 compatibility shim */


/*
** Compute 10 to the E-th power.  Examples:  E==1 results in 10.
** E==2 results in 100.  E==50 results in 1.0e50.
**
** This routine only works for values of E between 1 and 341.
*/


/*
** Compare the 19-character string zNum against the text representation
** value 2^63:  9223372036854775808.  Return negative, zero, or positive
** if zNum is less than, equal to, or greater than the string.
** Note that zNum must contain exactly 19 characters.
**
** Unlike memcmp() this routine is guaranteed to return the difference
** in the values of the last digit if the only difference is in the
** last digit.  So, for example,
**
**      compare2pow63("9223372036854775800", 1)
**
** will return -8.
*/


/*
** Log an error that is an API call on a connection pointer that should
** not have been used.  The "type" of connection pointer is given as the
** argument.  The zType is a word like "NULL" or "closed" or "invalid".
*/


/*
** The hashing function.
*/


/* Link pNew element into the hash table pH.  If pEntry!=0 then also
** insert pNew into the pEntry hash bucket.
*/


/* Resize the hash table so that it cantains "new_size" buckets.
**
** The hash table might fail to resize if sqlite3_malloc() fails or
** if the new size is the same as the prior size.
** Return TRUE if the resize occurs and false if not.
*/


/* This function (for internal use only) locates an element in an
** hash table that matches the given key.  If no element is found,
** a pointer to a static null element with HashElem.data==0 is returned.
** If pH is not NULL, then the hash for this key is written to *pH.
*/


/* Remove a single entry from the hash table given a pointer to that
** element and a hash on the element's key.
*/


/*
** On some systems, calls to fchown() will trigger a message in a security
** log if they come from non-root processes.  So avoid calling fchown() if
** we are not running as root.
*/


/*
** This is the xSetSystemCall() method of sqlite3_vfs for all of the
** "unix" VFSes.  Return SQLITE_OK opon successfully updating the
** system call pointer, or SQLITE_NOTFOUND if there is no configurable
** system call named zName.
*/


/*
** Return the value of a system call.  Return NULL if zName is not a
** recognized system call name.  NULL is also returned if the system call
** is currently undefined.
*/


/*
** Return the name of the first system call after zName.  If zName==NULL
** then return the name of the first system call.  Return NULL if zName
** is the last system call or if zName is not the name of a valid
** system call.
*/


/*
** Invoke open().  Do so multiple times, until it either succeeds or
** fails for some reason other than EINTR.
**
** If the file creation mode "m" is 0 then set it to the default for
** SQLite.  The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally
** 0644) as modified by the system umask.  If m is not 0, then
** make the file creation mode be exactly m ignoring the umask.
**
** The m parameter will be non-zero only when creating -wal, -journal,
** and -shm files.  We want those files to have *exactly* the same
** permissions as their original database, unadulterated by the umask.
** In that way, if a database file is -rw-rw-rw or -rw-rw-r-, and a
** transaction crashes and leaves behind hot journals, then any
** process that is able to write to the database will also be able to
** recover the hot journals.
*/


/*
** Helper function for printing out trace information from debugging
** binaries. This returns the string representation of the supplied
** integer lock-type.
*/


/*
** Print out information about all locking operations.
**
** This routine is used for troubleshooting locks on multithreaded
** platforms.  Enable by compiling with the -DSQLITE_LOCK_TRACE
** command-line option on the compiler.  This code is normally
** turned off.
*/


/*
** This routine translates a standard POSIX errno code into something
** useful to the clients of the sqlite3 functions.  Specifically, it is
** intended to translate a variety of "try again" errors into SQLITE_BUSY
** and a variety of "please close the file descriptor NOW" errors into
** SQLITE_IOERR
**
** Errors during initialization of locks, or file system support for locks,
** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately.
*/


/*
** Simplify a filename into its canonical form
** by making the following changes:
**
**  * removing any trailing and duplicate /
**  * convert /./ into just /
**  * convert /A/../ where A is any simple name into just /
**
** Changes are made in-place.  Return the new name length.
**
** The original filename is in z[0..n-1].  Return the number of
** characters in the simplified name.
*/


/*
** Find a unique file ID for the given absolute pathname.  Return
** a pointer to the vxworksFileId object.  This pointer is the unique
** file ID.
**
** The nRef field of the vxworksFileId object is incremented before
** the object is returned.  A new vxworksFileId object is created
** and added to the global list if necessary.
**
** If a memory allocation error occurs, return NULL.
*/


/*
** Decrement the reference count on a vxworksFileId object.  Free
** the object when the reference count reaches zero.
*/


/*
** Close a file descriptor.
**
** We assume that close() almost always works, since it is only in a
** very sick application or on a very sick platform that it might fail.
** If it does fail, simply leak the file descriptor, but do log the
** error.
**
** Note that it is not safe to retry close() after EINTR since the
** file descriptor might have already been reused by another thread.
** So we don't even try to recover from an EINTR.  Just log the error
** and move on.
*/


/*
** Close all file descriptors accumuated in the unixInodeInfo->pUnused list.
*/


/*
** Release a unixInodeInfo structure previously allocated by findInodeInfo().
**
** The global mutex must be held when this routine is called, but the mutex
** on the inode being deleted must NOT be held.
*/


/*
** Given a file descriptor, locate the unixInodeInfo object that
** describes that file descriptor.  Create a new one if necessary.  The
** return value might be uninitialized if an error occurs.
**
** The global mutex must held when calling this routine.
**
** Return an appropriate error code.
*/


/*
** Return TRUE if pFile has been renamed or unlinked since it was first opened.
*/


/*
** Check a unixFile that is a database.  Verify the following:
**
** (1) There is exactly one hard link on the file
** (2) The file is not a symbolic link
** (3) The file has not been renamed or unlinked
**
** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right.
*/


/*
** Attempt to set a system-lock on the file pFile.  The lock is
** described by pLock.
**
** If the pFile was opened read/write from unix-excl, then the only lock
** ever obtained is an exclusive lock, and it is obtained exactly once
** the first time any lock is attempted.  All subsequent system locking
** operations become no-ops.  Locking operations still happen internally,
** in order to coordinate access between separate database connections
** within this process, but all of that is handled in memory and the
** operating system does not participate.
**
** This function is a pass-through to fcntl(F_SETLK) if pFile is using
** any VFS other than "unix-excl" or if pFile is opened on "unix-excl"
** and is read-only.
**
** Zero is returned if the call completes successfully, or -1 if a call
** to fcntl() fails. In this case, errno is set appropriately (by fcntl()).
*/


/*
** Lock the file with the lock specified by parameter eFileLock - one
** of the following:
**
**     (1) SHARED_LOCK
**     (2) RESERVED_LOCK
**     (3) PENDING_LOCK
**     (4) EXCLUSIVE_LOCK
**
** Sometimes when requesting one lock state, additional lock states
** are inserted in between.  The locking might fail on one of the later
** transitions leaving the lock state different from what it started but
** still short of its goal.  The following chart shows the allowed
** transitions and the inserted intermediate states:
**
**    UNLOCKED -> SHARED
**    SHARED -> RESERVED
**    SHARED -> (PENDING) -> EXCLUSIVE
**    RESERVED -> (PENDING) -> EXCLUSIVE
**    PENDING -> EXCLUSIVE
**
** This routine will only increase a lock.  Use the sqlite3OsUnlock()
** routine to lower a locking level.
*/


/*
** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
** must be either NO_LOCK or SHARED_LOCK.
**
** If the locking level of the file descriptor is already at or below
** the requested locking level, this routine is a no-op.
*/


/*
** This function performs the parts of the "close file" operation
** common to all locking schemes. It closes the directory and file
** handles, if they are valid, and sets all fields of the unixFile
** structure to 0.
**
** It is *not* necessary to hold the mutex when this routine is called,
** even on VxWorks.  A mutex will be acquired on VxWorks by the
** vxworksReleaseFileId() routine.
*/


/*
** Close a file.
*/


/******************************************************************************
****************************** No-op Locking **********************************
**
** Of the various locking implementations available, this is by far the
** simplest:  locking is ignored.  No attempt is made to lock the database
** file for reading or writing.
**
** This locking mode is appropriate for use on read-only databases
** (ex: databases that are burned into CD-ROM, for example.)  It can
** also be used if the application employs some external mechanism to
** prevent simultaneous access of the same database by two or more
** database connections.  But there is a serious risk of database
** corruption if this locking mode is used in situations where multiple
** database connections are accessing the same database file at the same
** time and one or more of those connections are writing.
*/


/*
** Lock the file with the lock specified by parameter eFileLock - one
** of the following:
**
**     (1) SHARED_LOCK
**     (2) RESERVED_LOCK
**     (3) PENDING_LOCK
**     (4) EXCLUSIVE_LOCK
**
** Sometimes when requesting one lock state, additional lock states
** are inserted in between.  The locking might fail on one of the later
** transitions leaving the lock state different from what it started but
** still short of its goal.  The following chart shows the allowed
** transitions and the inserted intermediate states:
**
**    UNLOCKED -> SHARED
**    SHARED -> RESERVED
**    SHARED -> (PENDING) -> EXCLUSIVE
**    RESERVED -> (PENDING) -> EXCLUSIVE
**    PENDING -> EXCLUSIVE
**
** This routine will only increase a lock.  Use the sqlite3OsUnlock()
** routine to lower a locking level.
**
** With dotfile locking, we really only support state (4): EXCLUSIVE.
** But we track the other locking levels internally.
*/


/*
** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
** must be either NO_LOCK or SHARED_LOCK.
**
** If the locking level of the file descriptor is already at or below
** the requested locking level, this routine is a no-op.
**
** When the locking level reaches NO_LOCK, delete the lock file.
*/


/*
** Close a file.  Make sure the lock has been released before closing.
*/


/*
** Lock the file with the lock specified by parameter eFileLock - one
** of the following:
**
**     (1) SHARED_LOCK
**     (2) RESERVED_LOCK
**     (3) PENDING_LOCK
**     (4) EXCLUSIVE_LOCK
**
** Sometimes when requesting one lock state, additional lock states
** are inserted in between.  The locking might fail on one of the later
** transitions leaving the lock state different from what it started but
** still short of its goal.  The following chart shows the allowed
** transitions and the inserted intermediate states:
**
**    UNLOCKED -> SHARED
**    SHARED -> RESERVED
**    SHARED -> (PENDING) -> EXCLUSIVE
**    RESERVED -> (PENDING) -> EXCLUSIVE
**    PENDING -> EXCLUSIVE
**
** flock() only really support EXCLUSIVE locks.  We track intermediate
** lock states in the sqlite3_file structure, but all locks SHARED or
** above are really EXCLUSIVE locks and exclude all other processes from
** access the file.
**
** This routine will only increase a lock.  Use the sqlite3OsUnlock()
** routine to lower a locking level.
*/


/*
** Lock the file with the lock specified by parameter eFileLock - one
** of the following:
**
**     (1) SHARED_LOCK
**     (2) RESERVED_LOCK
**     (3) PENDING_LOCK
**     (4) EXCLUSIVE_LOCK
**
** Sometimes when requesting one lock state, additional lock states
** are inserted in between.  The locking might fail on one of the later
** transitions leaving the lock state different from what it started but
** still short of its goal.  The following chart shows the allowed
** transitions and the inserted intermediate states:
**
**    UNLOCKED -> SHARED
**    SHARED -> RESERVED
**    SHARED -> (PENDING) -> EXCLUSIVE
**    RESERVED -> (PENDING) -> EXCLUSIVE
**    PENDING -> EXCLUSIVE
**
** Semaphore locks only really support EXCLUSIVE locks.  We track intermediate
** lock states in the sqlite3_file structure, but all locks SHARED or
** above are really EXCLUSIVE locks and exclude all other processes from
** access the file.
**
** This routine will only increase a lock.  Use the sqlite3OsUnlock()
** routine to lower a locking level.
*/


/*
 ** Close a file.
 */


/*
** This is a utility for setting or clearing a bit-range lock on an
** AFP filesystem.
**
** Return SQLITE_OK on success, SQLITE_BUSY on failure.
*/


/*
** Close a file & cleanup AFP specific locking context
*/


/*
** Seek to the offset passed as the second argument, then read cnt
** bytes into pBuf. Return the number of bytes actually read.
**
** NB:  If you define USE_PREAD or USE_PREAD64, then it might also
** be necessary to define _XOPEN_SOURCE to be 500.  This varies from
** one system to another.  Since SQLite does not define USE_PREAD
** in any form by default, we will not attempt to define _XOPEN_SOURCE.
** See tickets #2741 and #2681.
**
** To avoid stomping the errno value on a failed read the lastErrno value
** is set before returning.
*/


/*
** Read data from a file into a buffer.  Return SQLITE_OK if all
** bytes were read successfully and SQLITE_IOERR if anything goes
** wrong.
*/


/*
** Attempt to seek the file-descriptor passed as the first argument to
** absolute offset iOff, then attempt to write nBuf bytes of data from
** pBuf to it. If an error occurs, return -1 and set *piErrno. Otherwise,
** return the actual number of bytes written (which may be less than
** nBuf).
*/


/*
** Write data from a buffer into a file.  Return SQLITE_OK on success
** or some other error code on failure.
*/


/*
** The fsync() system call does not work as advertised on many
** unix systems.  The following procedure is an attempt to make
** it work better.
**
** The SQLITE_NO_SYNC macro disables all fsync()s.  This is useful
** for testing when we want to run through the test suite quickly.
** You are strongly advised *not* to deploy with SQLITE_NO_SYNC
** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash
** or power failure will likely corrupt the database file.
**
** SQLite sets the dataOnly flag if the size of the file is unchanged.
** The idea behind dataOnly is that it should only write the file content
** to disk, not the inode.  We only set dataOnly if the file size is
** unchanged since the file size is part of the inode.  However,
** Ted Ts'o tells us that fdatasync() will also write the inode if the
** file size has changed.  The only real difference between fdatasync()
** and fsync(), Ted tells us, is that fdatasync() will not flush the
** inode if the mtime or owner or other inode attributes have changed.
** We only care about the file size, not the other file attributes, so
** as far as SQLite is concerned, an fdatasync() is always adequate.
** So, we always use fdatasync() if it is available, regardless of
** the value of the dataOnly flag.
*/


/*
** Open a file descriptor to the directory containing file zFilename.
** If successful, *pFd is set to the opened file descriptor and
** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM
** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined
** value.
**
** The directory file descriptor is used for only one thing - to
** fsync() a directory to make sure file creation and deletion events
** are flushed to disk.  Such fsyncs are not needed on newer
** journaling filesystems, but are required on older filesystems.
**
** This routine can be overridden using the xSetSysCall interface.
** The ability to override this routine was added in support of the
** chromium sandbox.  Opening a directory is a security risk (we are
** told) so making it overrideable allows the chromium sandbox to
** replace this routine with a harmless no-op.  To make this routine
** a no-op, replace it with a stub that returns SQLITE_OK but leaves
** *pFd set to a negative number.
**
** If SQLITE_OK is returned, the caller is responsible for closing
** the file descriptor *pFd using close().
*/


/*
** Determine the current size of a file in bytes
*/


/*
** This function is called to handle the SQLITE_FCNTL_SIZE_HINT
** file-control operation.  Enlarge the database to nBytes in size
** (rounded up to the next chunk-size).  If the database is already
** nBytes or larger, this routine is a no-op.
*/


/*
** If *pArg is initially negative then this is a query.  Set *pArg to
** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
**
** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags.
*/


/*
** Information and control of an open file handle.
*/


/*
** Return the sector size in bytes of the underlying block device for
** the specified file. This is almost always 512 bytes, but may be
** larger for some devices.
**
** SQLite code assumes this function cannot fail. It also assumes that
** if two files are created in the same file-system directory (i.e.
** a database and its journal file) that the sector size will be the
** same for both.
*/


/*
** Return the device characteristics for the file.
**
** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default.
** However, that choice is controversial since technically the underlying
** file system does not always provide powersafe overwrites.  (In other
** words, after a power-loss event, parts of the file that were never
** written might end up being altered.)  However, non-PSOW behavior is very,
** very rare.  And asserting PSOW makes a large reduction in the amount
** of required I/O for journaling, since a lot of padding is eliminated.
**  Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control
** available to turn it off and URI query parameter available to turn it off.
*/


/*
** Return the system page size.
**
** This function should not be called directly by other code in this file.
** Instead, it should be called via macro osGetpagesize().
*/


/*
** Use F_GETLK to check whether or not there are any readers with open
** wal-mode transactions in other processes on database file pFile. If
** no error occurs, return SQLITE_OK and set (*piOut) to 1 if there are
** such transactions, or 0 otherwise. If an error occurs, return an
** SQLite error code. The final value of *piOut is undefined in this
** case.
*/


/*
** Apply posix advisory locks for all bytes from ofst through ofst+n-1.
**
** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking
** otherwise.
*/


/*
** Return the minimum number of 32KB shm regions that should be mapped at
** a time, assuming that each mapping must be an integer multiple of the
** current system page-size.
**
** Usually, this is 1. The exception seems to be systems that are configured
** to use 64KB pages - in this case each mapping must cover at least two
** shm regions.
*/


/*
** Purge the unixShmNodeList list of all entries with unixShmNode.nRef==0.
**
** This is not a VFS shared-memory method; it is a utility function called
** by VFS shared-memory methods.
*/


/*
** The DMS lock has not yet been taken on shm file pShmNode. Attempt to
** take it now. Return SQLITE_OK if successful, or an SQLite error
** code otherwise.
**
** If the DMS cannot be locked because this is a readonly_shm=1
** connection and no other process already holds a lock, return
** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1.
*/


/*
** Open a shared-memory area associated with open database file pDbFd.
** This particular implementation uses mmapped files.
**
** The file used to implement shared-memory is in the same directory
** as the open database file and has the same name as the open database
** file with the "-shm" suffix added.  For example, if the database file
** is "/home/user1/config.db" then the file that is created and mmapped
** for shared memory will be called "/home/user1/config.db-shm".
**
** Another approach to is to use files in /dev/shm or /dev/tmp or an
** some other tmpfs mount. But if a file in a different directory
** from the database file is used, then differing access permissions
** or a chroot() might cause two different processes on the same
** database to end up using different files for shared memory -
** meaning that their memory would not really be shared - resulting
** in database corruption.  Nevertheless, this tmpfs file usage
** can be enabled at compile-time using -DSQLITE_SHM_DIRECTORY="/dev/shm"
** or the equivalent.  The use of the SQLITE_SHM_DIRECTORY compile-time
** option results in an incompatible build of SQLite;  builds of SQLite
** that with differing SQLITE_SHM_DIRECTORY settings attempt to use the
** same database file at the same time, database corruption will likely
** result. The SQLITE_SHM_DIRECTORY compile-time option is considered
** "unsupported" and may go away in a future SQLite release.
**
** When opening a new shared-memory file, if no other instances of that
** file are currently open, in this process or in other processes, then
** the file must be truncated to zero length or have its header cleared.
**
** If the original database file (pDbFd) is using the "unix-excl" VFS
** that means that an exclusive lock is held on the database file and
** that no other processes are able to read or write the database.  In
** that case, we do not really need shared memory.  No shared memory
** file is created.  The shared memory will be simulated with heap memory.
*/