/* find or add function at index <t_num>, and return pointer */ struct udft_entry * add_udf(int t_num) { struct udft_entry **udf_ptr = &first_udf; int i; while (*udf_ptr) { if (equals(t_num, (*udf_ptr)->udf_name)) return (*udf_ptr); udf_ptr = &((*udf_ptr)->next_udf); } /* get here => not found. udf_ptr points at first_udf or * next_udf field of last udf */ if (is_builtin_function(t_num)) int_warn(t_num, "Warning : udf shadowed by built-in function of the same name"); /* create and return a new udf slot */ *udf_ptr = (struct udft_entry *) gp_alloc(sizeof(struct udft_entry), "function"); (*udf_ptr)->next_udf = (struct udft_entry *) NULL; (*udf_ptr)->definition = NULL; (*udf_ptr)->at = NULL; (*udf_ptr)->udf_name = gp_alloc (token_len(t_num)+1, "user func"); copy_str((*udf_ptr)->udf_name, t_num, token_len(t_num)+1); for (i = 0; i < MAX_NUM_VAR; i++) (void) Ginteger(&((*udf_ptr)->dummy_values[i]), 0); return (*udf_ptr); }
/* substitute output from ` ` * *strp points to the input string. (*strp)[current] is expected to * be the initial back tic. Characters through the following back tic * are replaced by the output of the command. extend_input_line() * is called to extend *strp array if needed. */ static void substitute(char **strp, size_t *str_lenp, int current) { char *last; char c; char *str, *pgm, *rest = NULL; char *output; size_t pgm_len, rest_len = 0; int output_pos; /* forgive missing closing backquote at end of line */ str = *strp + current; last = str; while (*++last) { if (*last == '`') break; } pgm_len = last - str; pgm = gp_alloc(pgm_len, "command string"); safe_strncpy(pgm, str + 1, pgm_len); /* omit ` to leave room for NUL */ /* save rest of line, if any */ if (*last) { last++; /* advance past ` */ rest_len = strlen(last) + 1; if (rest_len > 1) { rest = gp_alloc(rest_len, "input line copy"); strcpy(rest, last); } } /* do system call */ (void) do_system_func(pgm, &output); free(pgm); /* now replace ` ` with output */ output_pos = 0; while ((c = output[output_pos++])) { if (c != '\n' && c != '\r') (*strp)[current++] = c; if (current == *str_lenp) extend_input_line(); } (*strp)[current] = 0; free(output); /* tack on rest of line to output */ if (rest) { while (current + rest_len > *str_lenp) extend_input_line(); strcpy(*strp + current, rest); free(rest); } screen_ok = FALSE; }
/* * Read commands from an initialization file. * where = 0: look for gnuplotrc in system shared directory * where = 1: look for .gnuplot in current directory * where = 2: look for .gnuplot in home directory */ static void load_rcfile(int where) { FILE *plotrc = NULL; char *rcfile = NULL; if (skip_gnuplotrc) return; if (where == 0) { #ifdef GNUPLOT_SHARE_DIR # if defined(_Windows) /* retrieve path relative to gnuplot executable, * whose path is in szModuleName (winmain.c) */ rcfile = gp_alloc(strlen((char *)szPackageDir) + 1 + strlen(GNUPLOT_SHARE_DIR) + 1 + strlen("gnuplotrc") + 1, "rcfile"); strcpy(rcfile, (char *)szPackageDir); PATH_CONCAT(rcfile, GNUPLOT_SHARE_DIR); # else rcfile = (char *) gp_alloc(strlen(GNUPLOT_SHARE_DIR) + 1 + strlen("gnuplotrc") + 1, "rcfile"); strcpy(rcfile, GNUPLOT_SHARE_DIR); # endif PATH_CONCAT(rcfile, "gnuplotrc"); plotrc = fopen(rcfile, "r"); #endif } else if (where == 1) { #ifdef USE_CWDRC /* Allow check for a .gnuplot init file in the current directory */ /* This is a security risk, as someone might leave a malicious */ /* init file in a shared directory. */ plotrc = fopen(PLOTRC, "r"); #endif /* !USE_CWDRC */ } else if (where == 2 && user_homedir) { /* length of homedir + directory separator + length of file name + \0 */ int len = (user_homedir ? strlen(user_homedir) : 0) + 1 + strlen(PLOTRC) + 1; rcfile = gp_alloc(len, "rcfile"); strcpy(rcfile, user_homedir); PATH_CONCAT(rcfile, PLOTRC); plotrc = fopen(rcfile, "r"); } if (plotrc) { char *rc = gp_strdup(rcfile ? rcfile : PLOTRC); load_file(plotrc, rc, FALSE); push_terminal(0); /* needed if terminal or its options were changed */ } free(rcfile); }
/* * iso_alloc() allocates a iso_curve structure that can hold 'num' * points. */ struct iso_curve * iso_alloc(int num) { struct iso_curve *ip; ip = (struct iso_curve *) gp_alloc(sizeof(struct iso_curve), "iso curve"); ip->p_max = (num >= 0 ? num : 0); ip->p_count = 0; if (num > 0) { ip->points = (struct coordinate GPHUGE *) gp_alloc(num * sizeof(struct coordinate), "iso curve points"); } else ip->points = (struct coordinate GPHUGE *) NULL; ip->next = NULL; return (ip); }
/* * Generate new edge and append it to list, but only if both vertices are * defined. The list is referenced by p_edge and pe_tail (p_edge points on * first edge and pe_tail on last one). * Note, the list may be empty (pe_edge==pe_tail==NULL) on entry and exit. */ static edge_struct * add_edge( struct coordinate *point0, /* 2 vertices input */ struct coordinate *point1, edge_struct **p_edge, /* pointers to edge list in/out */ edge_struct **pe_tail) { edge_struct *pe_temp = NULL; #if 1 if (point0->type == INRANGE && point1->type == INRANGE) #else if (point0->type != UNDEFINED && point1->type != UNDEFINED) #endif { pe_temp = gp_alloc(sizeof(edge_struct), "contour edge"); pe_temp->poly[0] = NULL; /* clear links */ pe_temp->poly[1] = NULL; pe_temp->vertex[0] = point0; /* First vertex of edge. */ pe_temp->vertex[1] = point1; /* Second vertex of edge. */ pe_temp->next = NULL; pe_temp->position = INNER_MESH; /* default position in mesh */ if ((*pe_tail)) { (*pe_tail)->next = pe_temp; /* Stick new record as last one. */ } else { (*p_edge) = pe_temp; /* start new list if empty */ } (*pe_tail) = pe_temp; /* continue to last record. */ } return pe_temp; /* returns NULL, if no edge allocated */ }
generic * gp_realloc(generic *p, size_t size, const char *message) { char *res; /* the new allocation */ /* realloc(NULL,x) is meant to do malloc(x), but doesn't always */ if (!p) return gp_alloc(size, message); #ifndef NO_GIH res = GP_FARREALLOC(p, size); if (res == (char *) NULL) { FreeHelp(); /* out of memory, try to make some room */ #endif /* NO_GIH */ res = GP_FARREALLOC(p, size); /* try again */ if (res == (char *) NULL) { /* really out of memory */ if (message != NULL) { int_error(NO_CARET, "out of memory for %s", message); /* NOTREACHED */ } /* else we return NULL */ } #ifndef NO_GIH } #endif return (res); }
/* Makes mapping from real 3D coordinates, passed as coords array, to 2D terminal coordinates, then draws filled polygon */ void filled_polygon_common(int points, struct coordinate GPHUGE * coords, TBOOLEAN fixed, double z) { int i; double x, y; gpiPoint *icorners; icorners = gp_alloc(points * sizeof(gpiPoint), "filled_polygon3d corners"); for (i = 0; i < points; i++) { if (fixed) z = coords[i].z; map3d_xy_double(coords[i].x, coords[i].y, z, &x, &y); icorners[i].x = x; icorners[i].y = y; } #ifdef EXTENDED_COLOR_SPECS if ((term->flags & TERM_EXTENDED_COLOR)) { icorners[0].spec.gray = -1; /* force solid color */ } #endif if (default_fillstyle.fillstyle == FS_EMPTY) icorners->style = FS_OPAQUE; else icorners->style = style_from_fill(&default_fillstyle); term->filled_polygon(points, icorners); free(icorners); }
/* STR points to a label string, possibly with several lines separated by \n. Return the number of characters in the longest line. If LINES is not NULL, set *LINES to the number of lines in the label. */ int label_width(const char *str, int *lines) { char *lab = NULL, *s, *e; int mlen, len, l; if (!str || *str == '\0') { if (lines) *lines = 0; return (0); } l = mlen = len = 0; lab = gp_alloc(strlen(str) + 2, "in label_width"); strcpy(lab, str); strcat(lab, "\n"); s = lab; while ((e = (char *) strchr(s, '\n')) != NULL) { *e = '\0'; len = estimate_strlen(s); /* = e-s ? */ if (len > mlen) mlen = len; if (len || l || *str == '\n') l++; s = ++e; } /* lines = NULL => not interested - div */ if (lines) *lines = l; free(lab); return (mlen); }
static void create_and_set_var( double val, char *prefix, char *base, char *suffix ) { int len; char *varname; struct udvt_entry *udv_ptr; t_value data; Gcomplex( &data, val, 0.0 ); /* data is complex, real=val, imag=0.0 */ /* In case prefix (or suffix) is NULL - make them empty strings */ prefix = prefix ? prefix : ""; suffix = suffix ? suffix : ""; len = strlen(prefix) + strlen(base) + strlen(suffix) + 1; varname = (char *)gp_alloc( len, "create_and_set_var" ); sprintf( varname, "%s%s%s", prefix, base, suffix ); /* Note that add_udv_by_name() checks if the name already exists, and * returns the existing ptr if found. It also allocates memory for * its own copy of the varname. */ udv_ptr = add_udv_by_name(varname); udv_ptr->udv_value = data; udv_ptr->udv_undef = FALSE; free( varname ); }
void init_memory() { extend_input_line(); extend_token_table(); replot_line = gp_alloc(1, "string"); *replot_line = NUL; }
/* * cp_binomial() computes the binomial coefficients needed for BEZIER stuff * and stores them into an array which is hooked to sdat. * (MGR 1992) */ static double * cp_binomial(int points) { double *coeff; int n, k; int e; e = points; /* well we're going from k=0 to k=p_count-1 */ coeff = gp_alloc(e * sizeof(double), "bezier coefficients"); n = points - 1; e = n / 2; /* HBB 990205: calculate these in 'logarithmic space', * as they become _very_ large, with growing n (4^n) */ coeff[0] = 0.0; for (k = 0; k < e; k++) { coeff[k + 1] = coeff[k] + log(((double) (n - k)) / ((double) (k + 1))); } for (k = n; k >= e; k--) coeff[k] = coeff[n - k]; return (coeff); }
/* * iso_extend() reallocates a iso_curve structure to hold "num" * points. This will either expand or shrink the storage. */ void iso_extend(struct iso_curve *ip, int num) { if (num == ip->p_max) return; #if defined(DOS16) || defined(WIN16) /* Make sure we do not allocate more than 64k points in msdos since * indexing is done with 16-bit int * Leave some bytes for malloc maintainance. */ if (num > 32700) int_error(NO_CARET, "Array index must be less than 32k in msdos"); #endif /* 16bit (Win)Doze */ if (num > 0) { if (ip->points == NULL) { ip->points = (struct coordinate GPHUGE *) gp_alloc(num * sizeof(struct coordinate), "iso curve points"); } else { ip->points = (struct coordinate GPHUGE *) gp_realloc(ip->points, num * sizeof(struct coordinate), "expanding curve points"); } ip->p_max = num; } else { if (ip->points != (struct coordinate GPHUGE *) NULL) free(ip->points); ip->points = (struct coordinate GPHUGE *) NULL; ip->p_max = 0; } }
/* push onto load_file state stack essentially, we save information needed to undo the load_file changes called by load_file */ void lf_push(FILE *fp) { LFS *lf; int argindex; lf = (LFS *) gp_alloc(sizeof(LFS), (char *) NULL); if (lf == (LFS *) NULL) { if (fp != (FILE *) NULL) (void) fclose(fp); /* it won't be otherwise */ int_error(c_token, "not enough memory to load file"); } lf->fp = fp; /* save this file pointer */ lf->interactive = interactive; /* save current state */ lf->inline_num = inline_num; /* save current line number */ lf->do_load_arg_substitution = do_load_arg_substitution; for (argindex = 0; argindex < 10; argindex++) { lf->call_args[argindex] = call_args[argindex]; call_args[argindex] = NULL; /* initially no args */ } lf->depth = lf_head ? lf_head->depth+1 : 0; /* recursion depth */ lf->c_token = c_token; /* Will be updated by caller */ lf->num_tokens = num_tokens;/* Will be updated by caller */ lf->input_line = NULL; /* Will be filled in by caller */ lf->tokens = NULL; /* Will be filled in by caller */ lf->name = NULL; /* Will be filled in by caller */ lf->prev = lf_head; /* link to stack */ lf_head = lf; }
/* Look for a gnuplot init file in current or home directory */ static void load_rcfile() { FILE *plotrc = NULL; char *rcfile = NULL; #ifdef NOCWDRC /* inhibit check of init file in current directory for security reasons */ #else plotrc = fopen(PLOTRC, "r"); #endif /* !NOCWDRC */ if (plotrc == NULL) { if (user_homedir) { /* len of homedir + directory separator + len of file name + \0 */ rcfile = (char *) gp_alloc((user_homedir ? strlen(user_homedir) : 0) + 1 + strlen(PLOTRC) + 1, "rcfile"); strcpy(rcfile, user_homedir); PATH_CONCAT(rcfile, PLOTRC); plotrc = fopen(rcfile, "r"); } } if (plotrc) { char *rc = gp_strdup(rcfile ? rcfile : PLOTRC); load_file(plotrc, rc, FALSE); push_terminal(0); /* needed if terminal or its options were changed */ } free(rcfile); }
generic * gp_realloc(generic *old, size_t size, const char *usage) { if (!old) return gp_alloc(size, usage); validate(old); /* if block gets moved, old block is marked free. If not, we'll * remark it later */ mark_free(old); { struct frame_struct *p = (struct frame_struct *) old - 1; size_t total = size + RESERVED_SIZE + 1; p = realloc(p, total); if (!p) int_error(NO_CARET, "Out of memory"); TRACE_ALLOC(("gp_realloc %d for %s (was %d)\n", (int) size, usage ? usage : "<unknown>", p->requested_size)); bytes_allocated += size - p->requested_size; mark(p, size, usage); return (generic *) (p + 1); } }
void f_concatenate(union argument *arg) { struct value a, b, result; (void) arg; /* avoid -Wunused warning */ (void) pop(&b); (void) pop(&a); if (b.type == INTGR) { int i = b.v.int_val; b.type = STRING; b.v.string_val = (char *)gp_alloc(32,"str_const"); #ifdef HAVE_SNPRINTF snprintf(b.v.string_val,32,"%d",i); #else sprintf(b.v.string_val,"%d",i); #endif } if (a.type != STRING || b.type != STRING) int_error(NO_CARET, "internal error : STRING operator applied to non-STRING type"); (void) Gstring(&result, gp_stradd(a.v.string_val, b.v.string_val)); gpfree_string(&a); gpfree_string(&b); push(&result); gpfree_string(&result); /* free string allocated within gp_stradd() */ }
/* * In-line data blocks are implemented as a here-document: * $FOO << EOD * data line 1 * data line 2 * ... * EOD * * The data block name must begin with $ followed by a letter. * The string EOD is arbitrary; lines of data will be read from the input stream * until the leading characters on the line match the given character string. * No attempt is made to parse the data at the time it is read in. */ void datablock_command() { FILE *fin; char *name, *eod; int nlines; int nsize = 4; struct udvt_entry *datablock; char dataline[MAX_LINE_LEN+1]; if (!isletter(c_token+1)) int_error(c_token, "illegal datablock name"); /* Create or recycle a datablock with the requested name */ name = parse_datablock_name(); datablock = add_udv_by_name(name); if (!datablock->udv_undef) gpfree_datablock(&datablock->udv_value); datablock->udv_undef = FALSE; datablock->udv_value.type = DATABLOCK; datablock->udv_value.v.data_array = NULL; if (!equals(c_token, "<<") || !isletter(c_token+1)) int_error(c_token, "data block name must be followed by << EODmarker"); c_token++; eod = gp_alloc(token[c_token].length +2, "datablock"); copy_str(&eod[0], c_token, token[c_token].length + 2); c_token++; /* Read in and store data lines until EOD */ fin = (lf_head == NULL) ? stdin : lf_head->fp; if (!fin) int_error(NO_CARET,"attempt to define data block from invalid context"); for (nlines = 0; fgets(dataline, MAX_LINE_LEN, fin); nlines++) { int n; if (!strncmp(eod, dataline, strlen(eod))) break; /* Allocate space for data lines plus at least 2 empty lines at the end. */ if (nlines >= nsize-4) { nsize *= 2; datablock->udv_value.v.data_array = gp_realloc( datablock->udv_value.v.data_array, nsize * sizeof(char *), "datablock"); memset(&datablock->udv_value.v.data_array[nlines], 0, (nsize - nlines) * sizeof(char *)); } /* Strip trailing newline character */ n = strlen(dataline); if (n > 0 && dataline[n - 1] == '\n') dataline[n - 1] = NUL; datablock->udv_value.v.data_array[nlines] = gp_strdup(dataline); } inline_num += nlines + 1; /* Update position in input file */ free(eod); return; }
/* * Allocate a new string and initialize it by concatenating two * existing strings. */ char * gp_stradd(const char *a, const char *b) { char *new = gp_alloc(strlen(a)+strlen(b)+1,"gp_stradd"); strcpy(new,a); strcat(new,b); return new; }
/* * Read commands from an initialization file. * where = 0: look for gnuplotrc in system shared directory * where = 1: look for .gnuplot in current directory * where = 2: look for .gnuplot in home directory */ static void load_rcfile(int where) { FILE *plotrc = NULL; char *rcfile = NULL; if (skip_gnuplotrc) return; if (where == 0) { #ifdef GNUPLOT_SHARE_DIR # if defined(_WIN32) || defined(MSDOS) || defined(OS2) rcfile = RelativePathToGnuplot(GNUPLOT_SHARE_DIR "\\gnuplotrc"); # else rcfile = (char *) gp_alloc(strlen(GNUPLOT_SHARE_DIR) + 1 + strlen("gnuplotrc") + 1, "rcfile"); strcpy(rcfile, GNUPLOT_SHARE_DIR); PATH_CONCAT(rcfile, "gnuplotrc"); # endif plotrc = fopen(rcfile, "r"); #endif } else if (where == 1) { #ifdef USE_CWDRC /* Allow check for a .gnuplot init file in the current directory */ /* This is a security risk, as someone might leave a malicious */ /* init file in a shared directory. */ plotrc = fopen(PLOTRC, "r"); #endif /* !USE_CWDRC */ } else if (where == 2 && user_homedir) { /* length of homedir + directory separator + length of file name + \0 */ int len = (user_homedir ? strlen(user_homedir) : 0) + 1 + strlen(PLOTRC) + 1; rcfile = gp_alloc(len, "rcfile"); strcpy(rcfile, user_homedir); PATH_CONCAT(rcfile, PLOTRC); plotrc = fopen(rcfile, "r"); } if (plotrc) { char *rc = gp_strdup(rcfile ? rcfile : PLOTRC); load_file(plotrc, rc, 3); push_terminal(0); /* needed if terminal or its options were changed */ } free(rcfile); }
/* Output time given in seconds from year 2000 into string */ void f_strftime(union argument *arg) { struct value fmt, val; char *fmtstr, *buffer; int fmtlen, buflen, length; (void) arg; /* Avoid compiler warnings */ /* Retrieve parameters from top of stack */ pop(&val); pop(&fmt); if ( fmt.type != STRING ) int_error(NO_CARET, "First parameter to strftime must be a format string"); /* Prepare format string. * Make sure the resulting string not empty by adding a space. * Otherwise, the return value of gstrftime doesn't give enough * information. */ fmtlen = strlen(fmt.v.string_val) + 1; fmtstr = gp_alloc(fmtlen + 1, "f_strftime: fmt"); strncpy(fmtstr, fmt.v.string_val, fmtlen); strncat(fmtstr, " ", fmtlen); buflen = 80 + 2*fmtlen; buffer = gp_alloc(buflen, "f_strftime: buffer"); /* Get time_str */ length = gstrftime(buffer, buflen, fmtstr, real(&val)); if (length == 0 || length >= buflen) int_error(NO_CARET, "Resulting string is too long"); /* Remove trailing space */ assert(buffer[length-1] == ' '); buffer[length-1] = NUL; buffer = gp_realloc(buffer, strlen(buffer)+1, "f_strftime"); FPRINTF((stderr," strftime result = \"%s\"\n",buffer)); gpfree_string(&val); gpfree_string(&fmt); free(fmtstr); push(Gstring(&val, buffer)); }
void gen_interp(struct curve_points *plot) { spline_coeff *sc; double *bc; struct coordinate *new_points; int i, curves; int first_point, num_points; curves = num_curves(plot); new_points = gp_alloc((samples_1 + 1) * curves * sizeof(struct coordinate), "interpolation table"); first_point = 0; for (i = 0; i < curves; i++) { num_points = next_curve(plot, &first_point); switch (plot->plot_smooth) { case SMOOTH_CSPLINES: sc = cp_tridiag(plot, first_point, num_points); do_cubic(plot, sc, first_point, num_points, new_points + i * (samples_1 + 1)); free(sc); break; case SMOOTH_ACSPLINES: sc = cp_approx_spline(plot, first_point, num_points); do_cubic(plot, sc, first_point, num_points, new_points + i * (samples_1 + 1)); free(sc); break; case SMOOTH_BEZIER: case SMOOTH_SBEZIER: bc = cp_binomial(num_points); do_bezier(plot, bc, first_point, num_points, new_points + i * (samples_1 + 1)); free((char *) bc); break; case SMOOTH_KDENSITY: do_kdensity( plot, first_point, num_points, new_points + i * (samples_1 + 1)); break; default: /* keep gcc -Wall quiet */ ; } new_points[(i + 1) * (samples_1 + 1) - 1].type = UNDEFINED; first_point += num_points; } free(plot->points); plot->points = new_points; plot->p_max = curves * (samples_1 + 1); plot->p_count = plot->p_max - 1; return; }
unsigned int * gp_cairo_helper_coordval_to_chars(coordval* image, int M, int N, t_imagecolor color_mode) { int m,n; unsigned int *image255, *image255copy; rgb_color rgb1; rgb255_color rgb255; /* cairo image buffer, upper bits are alpha, then r, g and b * Depends on endianess */ image255 = (unsigned int*) gp_alloc(M*N*sizeof(unsigned int), "gp_cairo : draw image"); image255copy = image255; /* TrueColor 24-bit plot->color mode */ if (color_mode == IC_RGB) { for (n=0; n<N; n++) { for (m=0; m<M; m++) { rgb1.r = *image++; rgb1.g = *image++; rgb1.b = *image++; rgb255_from_rgb1( rgb1, &rgb255 ); *image255copy++ = (0xFF<<24) + (rgb255.r<<16) + (rgb255.g<<8) + rgb255.b; } } } else if (color_mode == IC_RGBA) { unsigned char alpha255; double alpha1; for (n=0; n<N; n++) { for (m=0; m<M; m++) { alpha255 = *(image+3); alpha1 = (float)alpha255 / 255.; rgb1.r = alpha1 * (*image++); rgb1.g = alpha1 * (*image++); rgb1.b = alpha1 * (*image++); image++; rgb255_from_rgb1( rgb1, &rgb255 ); *image255copy++ = (alpha255<<24) + (rgb255.r<<16) + (rgb255.g<<8) + rgb255.b; } } /* Palette plot->color lookup from gray value */ } else { for (n=0; n<N; n++) { for (m=0; m<M; m++) { if (isnan(*image)) { image++; *image255copy++ = 0x00000000; } else { rgb255maxcolors_from_gray( *image++, &rgb255 ); *image255copy++ = (0xFF<<24) + (rgb255.r<<16) + (rgb255.g<<8) + rgb255.b; } } } } return image255; }
/* lf_push is called from two different contexts: * load_file passes fp and file name (3rd param NULL) * do_string_and_free passes cmdline (1st and 2nd params NULL) * In either case the routines lf_push/lf_pop save and restore state * information that may be changed by executing commands from a file * or from the passed command line. */ void lf_push(FILE *fp, char *name, char *cmdline) { LFS *lf; int argindex; lf = (LFS *) gp_alloc(sizeof(LFS), (char *) NULL); if (lf == (LFS *) NULL) { if (fp != (FILE *) NULL) (void) fclose(fp); /* it won't be otherwise */ int_error(c_token, "not enough memory to load file"); } lf->fp = fp; /* save this file pointer */ lf->name = name; lf->cmdline = cmdline; lf->interactive = interactive; /* save current state */ lf->inline_num = inline_num; /* save current line number */ lf->call_argc = call_argc; /* Call arguments are irrelevant if invoked from do_string_and_free */ if (cmdline == NULL) { for (argindex = 0; argindex < 10; argindex++) { lf->call_args[argindex] = call_args[argindex]; call_args[argindex] = NULL; /* initially no args */ } } lf->depth = lf_head ? lf_head->depth+1 : 0; /* recursion depth */ if (lf->depth > STACK_DEPTH) int_error(NO_CARET, "load/eval nested too deeply"); lf->if_depth = if_depth; lf->if_open_for_else = if_open_for_else; lf->if_condition = if_condition; lf->c_token = c_token; lf->num_tokens = num_tokens; lf->tokens = gp_alloc((num_tokens+1) * sizeof(struct lexical_unit), "lf tokens"); memcpy(lf->tokens, token, (num_tokens+1) * sizeof(struct lexical_unit)); lf->input_line = gp_strdup(gp_input_line); lf->prev = lf_head; /* link to stack */ lf_head = lf; }
/* allocates a double vector with n elements */ double * vec(int n) { double *dp; if (n < 1) return NULL; dp = gp_alloc(n * sizeof(double), "vec"); return dp; }
void extend_token_table() { if (token_table_size == 0) { /* first time */ token = (struct lexical_unit *) gp_alloc(MAX_TOKENS * sizeof(struct lexical_unit), "token table"); token_table_size = MAX_TOKENS; } else { token = gp_realloc(token, (token_table_size + MAX_TOKENS) * sizeof(struct lexical_unit), "extend token table"); token_table_size += MAX_TOKENS; FPRINTF((stderr, "extending token table to %d elements\n", token_table_size)); } }
/* * The routine to evaluate the B-spline value at point t using knot vector * from function fetch_knot(), and the control points p_cntr. * Returns (x, y) of approximated B-spline. Note that p_cntr points on the * first control point to blend with. The B-spline is of order order. */ static void eval_bspline( double t, cntr_struct *p_cntr, int num_of_points, int order, int j, TBOOLEAN contr_isclosed, double *x, double *y) { int i, p; double ti, tikp, *dx, *dy; /* Copy p_cntr into it to make it faster. */ dx = gp_alloc((order + j) * sizeof(double), "contour b_spline"); dy = gp_alloc((order + j) * sizeof(double), "contour b_spline"); /* Set the dx/dy - [0] iteration step, control points (p==0 iterat.): */ for (i = j - order; i <= j; i++) { dx[i] = p_cntr->X; dy[i] = p_cntr->Y; p_cntr = p_cntr->next; } for (p = 1; p <= order; p++) { /* Iteration (b-spline level) counter. */ for (i = j; i >= j - order + p; i--) { /* Control points indexing. */ ti = fetch_knot(contr_isclosed, num_of_points, order, i); tikp = fetch_knot(contr_isclosed, num_of_points, order, i + order + 1 - p); if (ti == tikp) { /* Should not be a problems but how knows... */ } else { dx[i] = dx[i] * (t - ti) / (tikp - ti) + /* Calculate x. */ dx[i - 1] * (tikp - t) / (tikp - ti); dy[i] = dy[i] * (t - ti) / (tikp - ti) + /* Calculate y. */ dy[i - 1] * (tikp - t) / (tikp - ti); } } } *x = dx[j]; *y = dy[j]; free(dx); free(dy); }
/* support for dynamic size of input line */ void extend_input_line() { if (input_line_len == 0) { /* first time */ input_line = gp_alloc(MAX_LINE_LEN, "input_line"); input_line_len = MAX_LINE_LEN; input_line[0] = NUL; } else { input_line = gp_realloc(input_line, input_line_len + MAX_LINE_LEN, "extend input line"); input_line_len += MAX_LINE_LEN; FPRINTF((stderr, "extending input line to %d chars\n", input_line_len)); } }
/* * Called from plot2d.c (get_data) for "plot with table" */ TBOOLEAN tabulate_one_line(double v[MAXDATACOLS], struct value str[MAXDATACOLS], int ncols) { int col; FILE *outfile = (table_outfile) ? table_outfile : gpoutfile; struct value keep; if (table_filter_at) { evaluate_inside_using = TRUE; evaluate_at(table_filter_at, &keep); evaluate_inside_using = FALSE; if (undefined || isnan(real(&keep)) || real(&keep) == 0) return FALSE; } if (table_var == NULL) { char sep = (table_sep && *table_sep) ? *table_sep : '\t'; for (col = 0; col < ncols; col++) { if (str[col].type == STRING) fprintf(outfile, " %s", str[col].v.string_val); else fprintf(outfile, " %g", v[col]); if (col < ncols-1) fprintf(outfile, "%c", sep); } fprintf(outfile, "\n"); } else { char buf[64]; /* buffer large enough to hold %g + 2 extra chars */ char sep = (table_sep && *table_sep) ? *table_sep : '\t'; size_t size = sizeof(buf); char *line = (char *) gp_alloc(size, ""); size_t len = 0; line[0] = NUL; for (col = 0; col < ncols; col++) { if (str[col].type == STRING) { len = strappend(&line, &size, 0, str[col].v.string_val); } else { snprintf(buf, sizeof(buf), " %g", v[col]); len = strappend(&line, &size, len, buf); } if (col < ncols-1) { snprintf(buf, sizeof(buf), " %c", sep); len = strappend(&line, &size, len, buf); } } append_to_datablock(&table_var->udv_value, line); } return TRUE; }
char * getusername () { char *username = NULL; char *fullname = NULL; username=getenv("USER"); if (!username) username=getenv("USERNAME"); #ifdef HAVE_PWD_H if (username) { struct passwd *pwentry = NULL; pwentry=getpwnam(username); if (pwentry && strlen(pwentry->pw_gecos)) { fullname = gp_alloc(strlen(pwentry->pw_gecos)+1,"getusername"); strcpy(fullname, pwentry->pw_gecos); } else { fullname = gp_alloc(strlen(username)+1,"getusername"); strcpy(fullname, username); } } #elif defined(_Windows) if (username) { DWORD bufCharCount = INFO_BUFFER_SIZE; fullname = gp_alloc(INFO_BUFFER_SIZE + 1,"getusername"); if (!GetUserName(fullname,&bufCharCount)) { free(fullname); fullname = NULL; } } #else fullname = gp_alloc(strlen(username)+1,"getusername"); strcpy(fullname, username); #endif /* HAVE_PWD_H */ return fullname; }
/* * Solve five diagonal linear system equation. The five diagonal matrix is * defined via matrix M, right side is r, and solution X i.e. M * X = R. * Size of system given in n. Return TRUE if solution exist. * G. Engeln-Muellges/ F.Reutter: * "Formelsammlung zur Numerischen Mathematik mit Standard-FORTRAN-Programmen" * ISBN 3-411-01677-9 * * / m02 m03 m04 0 0 0 0 . . . \ / x0 \ / r0 \ * I m11 m12 m13 m14 0 0 0 . . . I I x1 I I r1 I * I m20 m21 m22 m23 m24 0 0 . . . I * I x2 I = I r2 I * I 0 m30 m31 m32 m33 m34 0 . . . I I x3 I I r3 I * . . . . . . . . . . . . * \ m(n-3)0 m(n-2)1 m(n-1)2 / \x(n-1)/ \r(n-1)/ * */ static int solve_five_diag(five_diag m[], double r[], double x[], int n) { int i; five_diag *hv; hv = gp_alloc((n + 1) * sizeof(five_diag), "five_diag help vars"); hv[0][0] = m[0][2]; if (hv[0][0] == 0) { free(hv); return FALSE; } hv[0][1] = m[0][3] / hv[0][0]; hv[0][2] = m[0][4] / hv[0][0]; hv[1][3] = m[1][1]; hv[1][0] = m[1][2] - hv[1][3] * hv[0][1]; if (hv[1][0] == 0) { free(hv); return FALSE; } hv[1][1] = (m[1][3] - hv[1][3] * hv[0][2]) / hv[1][0]; hv[1][2] = m[1][4] / hv[1][0]; for (i = 2; i < n; i++) { hv[i][3] = m[i][1] - m[i][0] * hv[i - 2][1]; hv[i][0] = m[i][2] - m[i][0] * hv[i - 2][2] - hv[i][3] * hv[i - 1][1]; if (hv[i][0] == 0) { free(hv); return FALSE; } hv[i][1] = (m[i][3] - hv[i][3] * hv[i - 1][2]) / hv[i][0]; hv[i][2] = m[i][4] / hv[i][0]; } hv[0][4] = 0; hv[1][4] = r[0] / hv[0][0]; for (i = 1; i < n; i++) { hv[i + 1][4] = (r[i] - m[i][0] * hv[i - 1][4] - hv[i][3] * hv[i][4]) / hv[i][0]; } x[n - 1] = hv[n][4]; x[n - 2] = hv[n - 1][4] - hv[n - 2][1] * x[n - 1]; for (i = n - 3; i >= 0; i--) x[i] = hv[i + 1][4] - hv[i][1] * x[i + 1] - hv[i][2] * x[i + 2]; free(hv); return TRUE; }