diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/PJ_cart.c | 65 | ||||
| -rw-r--r-- | src/pj_init.c | 13 | ||||
| -rw-r--r-- | src/pj_internal.c | 47 | ||||
| -rw-r--r-- | src/pj_obs_api.c | 234 | ||||
| -rw-r--r-- | src/pj_open_lib.c | 12 | ||||
| -rw-r--r-- | src/proj.def | 80 | ||||
| -rw-r--r-- | src/proj.h | 72 | ||||
| -rw-r--r-- | src/proj_internal.h | 4 | ||||
| -rw-r--r-- | src/projects.h | 1 |
9 files changed, 439 insertions, 89 deletions
diff --git a/src/PJ_cart.c b/src/PJ_cart.c index 169002ba..1373e870 100644 --- a/src/PJ_cart.c +++ b/src/PJ_cart.c @@ -236,14 +236,20 @@ int pj_cart_selftest (void) { PJ *P; PJ_OBS a, b, obs[2]; PJ_COORD coord[2]; + + PJ_INFO info; + PJ_PROJ_INFO pj_info; + PJ_GRID_INFO grid_info; + PJ_INIT_INFO init_info; + PJ_DERIVS derivs; PJ_FACTORS factors; + int err; size_t n, sz; double dist, h, t; char *args[3] = {"proj=utm", "zone=32", "ellps=GRS80"}; - char *arg = {" +proj=utm +zone=32 +ellps=GRS80"}; - char *arg_def; + char *arg = {"+proj=utm +zone=32 +ellps=GRS80"}; char buf[40]; /* An utm projection on the GRS80 ellipsoid */ @@ -251,11 +257,6 @@ int pj_cart_selftest (void) { if (0==P) return 1; - /* note arg is handcrafted to go undisturbed through get def reconstruction */ - arg_def = proj_definition_retrieve (P); - if (0!=strcmp(arg, arg_def)) - return 44; - proj_release (arg_def); /* Clean up */ proj_destroy (P); @@ -478,21 +479,50 @@ int pj_cart_selftest (void) { } proj_destroy(P); - /* Test proj_has_inverse() */ - P = proj_create(0, "+proj=august"); /* august has no inverse */ - if (proj_has_inverse(P)) { - proj_destroy(P); - return 60; + /* ********************************************************************** */ + /* Test info functions */ + /* ********************************************************************** */ + + /* proj_info() */ + /* this one is difficult to test, since the output changes with the setup */ + info = proj_info(); + if (info.version) { + char tmpstr[64]; + sprintf(tmpstr, "%d.%d.%d", info.major, info.minor, info.patch); + if (strcmp(info.version, tmpstr)) return 55; } + if (!info.release) return 56; + if (!info.searchpath) return 57; + + /* proj_pj_info() */ + P = proj_create(0, "+proj=august"); /* august has no inverse */ + if (proj_pj_info(P).has_inverse) { proj_destroy(P); return 60; } proj_destroy(P); - P = proj_create(0, "+proj=merc"); /* merc has an inverse */ - if (!proj_has_inverse(P)) { - proj_destroy(P); - return 61; - } + P = proj_create(0, arg); + pj_info = proj_pj_info(P); + if ( !pj_info.has_inverse ) { proj_destroy(P); return 61; } + if ( strcmp(pj_info.definition, arg) ) { proj_destroy(P); return 62; } + if ( strcmp(pj_info.id, "utm") ) { proj_destroy(P); return 63; } proj_destroy(P); + /* proj_grid_info() */ + grid_info = proj_grid_info("egm96_15.gtx"); + if ( strlen(grid_info.filename) == 0 ) return 64; + if ( strcmp(grid_info.gridname, "egm96_15.gtx") ) return 65; + grid_info = proj_grid_info("nonexistinggrid"); + if ( strlen(grid_info.filename) > 0 ) return 66; + + /* proj_init_info() */ + init_info = proj_init_info("unknowninit"); + if ( strlen(init_info.filename) != 0 ) return 67; + + init_info = proj_init_info("epsg"); + if ( strcmp(init_info.origin, "EPSG") ) return 69; + if ( strcmp(init_info.name, "epsg") ) return 68; + + + /* test proj_rtodms() and proj_dmstor() */ if (strcmp("180dN", proj_rtodms(buf, M_PI, 'N', 'S'))) return 70; @@ -536,6 +566,7 @@ int pj_cart_selftest (void) { proj_destroy(P); + return 0; } diff --git a/src/pj_init.c b/src/pj_init.c index 243174e1..7448fdb6 100644 --- a/src/pj_init.c +++ b/src/pj_init.c @@ -243,8 +243,9 @@ get_opt(projCtx ctx, paralist **start, PAFile fid, char *name, paralist *next, else { /* skip past word */ - while( *next_char && !isspace(*next_char) ) + while( *next_char && !isspace(*next_char) ) { next_char++; + } } } @@ -253,7 +254,6 @@ get_opt(projCtx ctx, paralist **start, PAFile fid, char *name, paralist *next, errno = 0; free(state); - return next; } @@ -280,8 +280,7 @@ get_defaults(projCtx ctx, paralist **start, paralist *next, char *name) { /************************************************************************/ /* get_init() */ /************************************************************************/ -static paralist * -get_init(projCtx ctx, paralist **start, paralist *next, char *name, int *found_def) { +static paralist *get_init(projCtx ctx, paralist **start, paralist *next, char *name, int *found_def) { char fname[MAX_PATH_FILENAME+ID_TAG_MAX+3], *opt; PAFile fid; paralist *init_items = NULL; @@ -330,6 +329,10 @@ get_init(projCtx ctx, paralist **start, paralist *next, char *name, int *found_d return next; } +paralist * pj_get_init(projCtx ctx, paralist **start, paralist *next, char *name, int *found_def) { + return get_init(ctx, start, next, name, found_def); +} + /************************************************************************/ /* pj_init_plus() */ /* */ @@ -466,7 +469,7 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { } } - /* in cae the parameter list only consist of a +init parameter + /* in case the parameter list only consist of a +init parameter it is expanded here (will not be handled in the above loop). */ if (pj_param(ctx, start, "tinit").i && argc == 1) { found_def = 0; diff --git a/src/pj_internal.c b/src/pj_internal.c index f3ca3566..31c299ac 100644 --- a/src/pj_internal.c +++ b/src/pj_internal.c @@ -167,6 +167,53 @@ void proj_context_inherit (PJ *parent, PJ *child) { +size_t pj_strlcpy(char *dst, const char *src, size_t siz) { +/******************************************************************* + Copy src to string dst of size siz. At most siz-1 characters + will be copied. Always NUL terminates (unless siz == 0). + Returns strlen(src); if retval >= siz, truncation occurred. + + + * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Source: http://www.i-pi.com/Training/EthicalHacking/Solutions/strlcpy.c + +********************************************************************/ + register char *d = dst; + register const char *s = src; + register size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + /* stuff below is *not* considered API, and will be moved to an "internal plumbing toolset" */ diff --git a/src/pj_obs_api.c b/src/pj_obs_api.c index b06f0823..b2929a07 100644 --- a/src/pj_obs_api.c +++ b/src/pj_obs_api.c @@ -390,9 +390,13 @@ PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *srid_from, const char ******************************************************************************/ PJ *P; - char buffer[256]; + char buffer[512]; + + strcpy(buffer, "+proj=pipeline +step +init="); + strncat(buffer, srid_from, 512-strlen(buffer)); + strncat(buffer, " +inv +step +init=", 512-strlen(buffer)); + strncat(buffer, srid_to, 512-strlen(buffer)); - sprintf(buffer, "+proj=pipeline +step +init=%s +inv +step +init=%s", srid_from, srid_to); P = proj_create(ctx, buffer); return P; @@ -509,11 +513,218 @@ void proj_context_destroy (PJ_CONTEXT *ctx) { } -/* Build a fully expanded proj_create() compatible representation of P */ -char *proj_definition_retrieve (PJ *P) { - if (0==P) - return 0; - return pj_get_def(P, 0); +/*****************************************************************************/ +PJ_INFO proj_info(void) { +/****************************************************************************** + Basic info about the current instance of the PROJ.4 library. + + Returns PJ_INFO struct. Searchpath member of the struct is truncated to 512 + characters. + +******************************************************************************/ + PJ_INFO info; + const char **paths; + char *tmpstr; + int i, n; + size_t len = 0; + + memset(&info, 0, sizeof(PJ_INFO)); + + info.major = PROJ_VERSION_MAJOR; + info.minor = PROJ_VERSION_MINOR; + info.patch = PROJ_VERSION_PATCH; + + /* This is a controlled environment, so no risk of sprintf buffer + overflow. A normal version string is xx.yy.zz which is 8 characters + long and there is room for 64 bytes in the version string. */ + sprintf(info.version, "%d.%d.%d", info.major, info.minor, info.patch); + + pj_strlcpy(info.release, pj_get_release(), sizeof(info.release)); + + + /* build search path string */ + tmpstr = getenv("HOME"); + if (tmpstr != NULL) { + pj_strlcpy(info.searchpath, tmpstr, sizeof(info.searchpath)); + } + + tmpstr = getenv("PROJ_LIB"); + if (tmpstr != NULL) { + if (strlen(info.searchpath) != 0) { + /* $HOME already in path */ + strcat(info.searchpath, ";"); + len = strlen(tmpstr); + strncat(info.searchpath, tmpstr, sizeof(info.searchpath)-len-1); + } else { + /* path is empty */ + pj_strlcpy(info.searchpath, tmpstr, sizeof(info.searchpath)); + } + } + + paths = proj_get_searchpath(); + n = proj_get_path_count(); + + for (i=0; i<n; i++) { + if (strlen(info.searchpath)+strlen(paths[i]) >= 511) + continue; + + if (strlen(info.searchpath) != 0) { + strcat(info.searchpath, ";"); + len = strlen(paths[i]); + strncat(info.searchpath, paths[i], sizeof(info.searchpath)-len-1); + } else { + pj_strlcpy(info.searchpath, paths[i], sizeof(info.searchpath)); + } + } + + return info; +} + + +/*****************************************************************************/ +PJ_PROJ_INFO proj_pj_info(const PJ *P) { +/****************************************************************************** + Basic info about a particular instance of a projection object. + + Returns PJ_PROJ_INFO struct. + +******************************************************************************/ + PJ_PROJ_INFO info; + char *def; + + memset(&info, 0, sizeof(PJ_PROJ_INFO)); + + if (!P) { + return info; + } + + /* projection id */ + if (pj_param(P->ctx, P->params, "tproj").i) + pj_strlcpy(info.id, pj_param(P->ctx, P->params, "sproj").s, sizeof(info.id)); + + /* projection description */ + pj_strlcpy(info.description, P->descr, sizeof(info.description)); + + /* projection definition */ + def = pj_get_def((PJ *)P, 0); /* pj_get_def takes a non-const PJ pointer */ + pj_strlcpy(info.definition, &def[1], sizeof(info.definition)); /* def includes a leading space */ + pj_dealloc(def); + + /* this does not take into account that a pipeline potentially does not */ + /* have an inverse. */ + info.has_inverse = (P->inv != 0 || P->inv3d != 0 || P->invobs != 0); + + return info; +} + + +/*****************************************************************************/ +PJ_GRID_INFO proj_grid_info(const char *gridname) { +/****************************************************************************** + Information about a named datum grid. + + Returns PJ_GRID_INFO struct. + +******************************************************************************/ + PJ_GRID_INFO info; + + /*PJ_CONTEXT *ctx = proj_context_create(); */ + PJ_CONTEXT *ctx = pj_get_default_ctx(); + PJ_GRIDINFO *gridinfo = pj_gridinfo_init(ctx, gridname); + memset(&info, 0, sizeof(PJ_GRID_INFO)); + + /* in case the grid wasn't found */ + if (gridinfo->filename == NULL) { + pj_gridinfo_free(ctx, gridinfo); + strcpy(info.format, "missing"); + return info; + } + + /* name of grid */ + pj_strlcpy(info.gridname, gridname, sizeof(info.gridname)); + + /* full path of grid */ + pj_find_file(ctx, gridname, info.filename, sizeof(info.filename)); + + /* grid format */ + pj_strlcpy(info.format, gridinfo->format, sizeof(info.format)); + + /* grid size */ + info.n_lon = gridinfo->ct->lim.lam; + info.n_lat = gridinfo->ct->lim.phi; + + /* cell size */ + info.cs_lon = gridinfo->ct->del.lam; + info.cs_lat = gridinfo->ct->del.phi; + + /* bounds of grid */ + info.lowerleft = gridinfo->ct->ll; + info.upperright.lam = info.lowerleft.lam + info.n_lon*info.cs_lon; + info.upperright.phi = info.lowerleft.phi + info.n_lat*info.cs_lat; + + pj_gridinfo_free(ctx, gridinfo); + + return info; +} + +/*****************************************************************************/ +PJ_INIT_INFO proj_init_info(const char *initname){ +/****************************************************************************** + Information about a named init file. + + Maximum length of initname is 64. + + Returns PJ_INIT_INFO struct. + + If the init file is not found all members of + the return struct are set to 0. If the init file is found, but it the + metadata is missing, the value is set to "Unknown". + +******************************************************************************/ + int file_found, def_found=0; + char param[80], key[74]; + paralist *start, *next; + PJ_INIT_INFO info; + PJ_CONTEXT *ctx = pj_get_default_ctx(); + + memset(&info, 0, sizeof(PJ_INIT_INFO)); + + file_found = pj_find_file(ctx, initname, info.filename, sizeof(info.filename)); + if (!file_found || strlen(initname) > 64) { + return info; + } + + pj_strlcpy(info.name, initname, sizeof(info.name)); + strcpy(info.origin, "Unknown"); + strcpy(info.version, "Unknown"); + strcpy(info.lastupdate, "Unknown"); + + pj_strlcpy(key, initname, 64); /* make room for ":metadata\0" at the end */ + strncat(key, ":metadata", 9); + strcpy(param, "+init="); + strncat(param, key, 73); + + start = pj_mkparam(param); + next = pj_get_init(ctx, &start, start, key, &def_found); + + if (pj_param(ctx, start, "tversion").i) { + pj_strlcpy(info.version, pj_param(ctx, start, "sversion").s, sizeof(info.version)); + } + + if (pj_param(ctx, start, "torigin").i) { + pj_strlcpy(info.origin, pj_param(ctx, start, "sorigin").s, sizeof(info.origin)); + } + + if (pj_param(ctx, start, "tlastupdate").i) { + pj_strlcpy(info.lastupdate, pj_param(ctx, start, "slastupdate").s, sizeof(info.lastupdate)); + } + + for ( ; start; start = next) { + next = start->next; + pj_dalloc(start); + } + + return info; } @@ -565,18 +776,9 @@ PJ_FACTORS proj_factors(const PJ *P, const LP lp) { } -/* Release, or free, memory that was retrieved by the above functions */ -void *proj_release (void *buffer) { - return pj_dealloc (buffer); -} - - double proj_torad (double angle_in_degrees) { return PJ_TORAD (angle_in_degrees);} double proj_todeg (double angle_in_radians) { return PJ_TODEG (angle_in_radians);} -int proj_has_inverse(PJ *P) { - return (P->inv != 0 || P->inv3d != 0 || P->invobs != 0); -} double proj_dmstor(const char *is, char **rs) { return dmstor(is, rs); diff --git a/src/pj_open_lib.c b/src/pj_open_lib.c index 859adede..08532beb 100644 --- a/src/pj_open_lib.c +++ b/src/pj_open_lib.c @@ -29,6 +29,7 @@ *****************************************************************************/ #define PJ_LIB__ +#include "proj_internal.h" #include <projects.h> #include <stdio.h> #include <string.h> @@ -86,10 +87,19 @@ void pj_set_searchpath ( int count, const char **path ) strcpy(search_path[i], path[i]); } } - + path_count = count; } +/* just a couple of helper functions that lets other functions + access the otherwise private search path */ +const char **proj_get_searchpath(void) { + return (const char **)search_path; +} + +int proj_get_path_count(void) { + return path_count; +} /************************************************************************/ /* pj_open_lib_ex() */ /************************************************************************/ diff --git a/src/proj.def b/src/proj.def index 835391ac..12816f1c 100644 --- a/src/proj.def +++ b/src/proj.def @@ -90,54 +90,56 @@ EXPORTS geod_polygon_clear @88 pj_run_selftests @89 - proj_create @90 - proj_create_argv @91 - proj_create_crs_to_crs @92 - proj_destroy @93 + pj_find_file @90 - proj_trans_obs @94 - proj_trans_coord @95 - proj_transform @96 - proj_transform_obs @97 - proj_transform_coord @98 - proj_roundtrip @99 + proj_create @91 + proj_create_argv @92 + proj_create_crs_to_crs @93 + proj_destroy @94 - proj_coord @100 - proj_obs @101 - proj_coord_error @102 - proj_obs_error @103 + proj_trans_obs @95 + proj_trans_coord @96 + proj_transform @97 + proj_transform_obs @98 + proj_transform_coord @99 + proj_roundtrip @100 - proj_errno @104 - proj_errno_set @105 - proj_errno_reset @106 - proj_errno_restore @107 - proj_context_errno_set @108 + proj_coord @101 + proj_obs @102 + proj_coord_error @103 + proj_obs_error @104 - proj_context_create @109 - proj_context_set @110 - proj_context_inherit @111 - proj_context_destroy @112 + proj_errno @105 + proj_errno_set @106 + proj_errno_reset @107 + proj_errno_restore @108 + proj_context_errno_set @109 - proj_lp_dist @113 - proj_xy_dist @114 - proj_xyz_dist @115 + proj_context_create @110 + proj_context_set @111 + proj_context_inherit @112 + proj_context_destroy @113 - proj_log_level @116 - proj_log_func @117 - proj_log_error @118 - proj_log_debug @119 - proj_log_trace @120 + proj_lp_dist @114 + proj_xy_dist @115 + proj_xyz_dist @116 - proj_definition_retrieve @121 - proj_derivatives @122 - proj_factors @123 - proj_release @124 + proj_log_level @117 + proj_log_func @118 + proj_log_error @119 + proj_log_debug @120 + proj_log_trace @121 - proj_torad @125 - proj_todeg @126 - proj_has_inverse @127 + proj_info @122 + proj_pj_info @123 + proj_grid_info @124 + proj_init_info @125 + + proj_torad @126 + proj_todeg @127 proj_rtodms @128 proj_dmstor @129 + proj_derivatives @130 + proj_factors @131 - pj_find_file @130 @@ -156,7 +156,7 @@ extern "C" { ************************************************************************/ #define PROJ_VERSION_MAJOR 10 #define PROJ_VERSION_MINOR 0 -#define PROJ_VERSION_MICRO 0 +#define PROJ_VERSION_PATCH 0 #ifndef PJ_VERSION #define PJ_VERSION 10##000##00 @@ -192,6 +192,19 @@ typedef struct PJ_FACTORS PJ_FACTORS; struct PJconsts; typedef struct PJconsts PJ; /* the PJ object herself */ +/* Data type for library level information */ +struct PJ_INFO; +typedef struct PJ_INFO PJ_INFO; + +struct PJ_PROJ_INFO; +typedef struct PJ_PROJ_INFO PJ_PROJ_INFO; + +struct PJ_GRID_INFO; +typedef struct PJ_GRID_INFO PJ_GRID_INFO; + +struct PJ_INIT_INFO; +typedef struct PJ_INIT_INFO PJ_INIT_INFO; + /* Omega, Phi, Kappa: Rotations */ typedef struct {double o, p, k;} PJ_OPK; @@ -275,6 +288,7 @@ struct PJ_OBS { unsigned int flags; /* additional data, intended for flags */ }; + struct PJ_DERIVS { double x_l, x_p; /* derivatives of x for lambda-phi */ double y_l, y_p; /* derivatives of y for lambda-phi */ @@ -291,6 +305,44 @@ struct PJ_FACTORS { }; +struct PJ_INFO { + char release[64]; /* Release info. Version + date */ + char version[64]; /* Full version number */ + int major; /* Major release number */ + int minor; /* Minor release number */ + int patch; /* Patch level */ + char searchpath[512]; /* Paths where init and grid files are */ + /* looked for. Paths are separated by */ + /* semi-colons. */ +}; + +struct PJ_PROJ_INFO { + char id[16]; /* Name of the projection in question */ + char description[128]; /* Description of the projection */ + char definition[512]; /* Projection definition */ + int has_inverse; /* 1 if an inverse mapping exists, 0 otherwise */ +}; + +struct PJ_GRID_INFO { + char gridname[32]; /* name of grid */ + char filename[260]; /* full path to grid */ + char format[8]; /* file format of grid */ + LP lowerleft; /* Coordinates of lower left corner */ + LP upperright; /* Coordinates of upper right corner */ + int n_lon, n_lat; /* Grid size */ + double cs_lon, cs_lat; /* Cell size of grid */ +}; + +struct PJ_INIT_INFO { + char name[32]; /* name of init file */ + char filename[260]; /* full path to the init file. */ + char version[32]; /* version of the init file */ + char origin[32]; /* origin of the file, e.g. EPSG */ + char lastupdate[16]; /* Date of last update in YYYY-MM-DD format */ +}; + + + /* The context type - properly namespaced synonym for projCtx */ struct projCtx_t; typedef struct projCtx_t PJ_CONTEXT; @@ -358,10 +410,14 @@ int proj_errno_reset (PJ *P); void proj_errno_restore (PJ *P, int err); -/* Build a fully expanded proj_create() compatible representation of P */ -char *proj_definition_retrieve (PJ *P); -/* ...and get rid of it safely */ -void *proj_release (void *buffer); +PJ_DERIVS proj_derivatives(const PJ *P, const LP lp); +PJ_FACTORS proj_factors(const PJ *P, const LP lp); + +/* Info functions - get information about various PROJ.4 entities */ +PJ_INFO proj_info(void); +PJ_PROJ_INFO proj_pj_info(const PJ *P); +PJ_GRID_INFO proj_grid_info(const char *gridname); +PJ_INIT_INFO proj_init_info(const char *initname); /* These are trivial, and while occasionaly useful in real code, primarily here to */ @@ -370,15 +426,9 @@ void *proj_release (void *buffer); double proj_torad (double angle_in_degrees); double proj_todeg (double angle_in_radians); -/* Check if a projection has an inverse mapping */ -int proj_has_inverse(PJ *P); - double proj_dmstor(const char *is, char **rs); char* proj_rtodms(char *s, double r, int pos, int neg); -PJ_DERIVS proj_derivatives(const PJ *P, const LP lp); -PJ_FACTORS proj_factors(const PJ *P, const LP lp); - #ifdef __cplusplus } #endif diff --git a/src/proj_internal.h b/src/proj_internal.h index da457077..0b74b563 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -107,6 +107,10 @@ void proj_log_func (PJ_CONTEXT *ctx, void *app_data, PJ_LOG_FUNCTION log); /* Lowest level: Minimum support for fileapi */ void proj_fileapi_set (PJ *P, void *fileapi); +const char **proj_get_searchpath(void); +int proj_get_path_count(void); + +size_t pj_strlcpy(char *dst, const char *src, size_t siz); #ifdef __cplusplus } diff --git a/src/projects.h b/src/projects.h index 710d5022..872bf816 100644 --- a/src/projects.h +++ b/src/projects.h @@ -712,6 +712,7 @@ void pj_prepare (PJ *P, const char *description, void (*freeup)(struct PJconsts paralist *pj_clone_paralist( const paralist* ); paralist *pj_search_initcache( const char *filekey ); void pj_insert_initcache( const char *filekey, const paralist *list); +paralist *pj_get_init(projCtx ctx, paralist **start, paralist *next, char *name, int *found_def); double *pj_enfn(double); double pj_mlfn(double, double, double, double *); |
