void spf_load ( char *filnam, int *iret ) /************************************************************************ * spf_load * * * * This function loads the file contents into the "_spfBuffer". If the * * file does not exist, it will not be created & nothing will be read. * * * * spf_load ( filnam, iret ) * * * * Input parameters: * * *filnam char file name with full path * * * * Output parameters: * * *iret int Return code * * 4 - Reach the end of file * * 0 - Normal * * -1 - File does not exist * * -2 - File cannot be opened * * -4 - Failure to read SPF file * * -7 - Failure to allocate buffer * * * ** * * Log: * * J. Wu/GSC 6/01 create * * J. Wu/GSC 7/01 allow access to read-only SPF files * * H. Zeng/SAIC 9/04 spf_read() para. list change * ***********************************************************************/ { int flen, ier; FILE *fptr; /*---------------------------------------------------------------------*/ *iret = G_NORMAL; fptr = NULL; if ( _initSPF != G_TRUE ) spf_init( &ier ); spf_open( filnam, FALSE, &fptr, &flen, iret ); if ( *iret >= 0 ) { spf_read( fptr, filnam, flen, iret ); } if ( fptr != NULL ) { spf_close( fptr, &ier ); } }
/* QUERY -- Query the user for the value of a parameter. Prompt with the * current value if any. Keep this up until we can push a reasonable value. * Also, store the new value in the parameter (except for list params, where, * since the values are not kept, all that may change is P_LEOF if seen). * Give prompt, or name if none, current value and range if int, real or * filename. Accept CR to leave value unchanged, else take the string * entered to be the new value. Repeat until parameter value is in range. * We mean to talk straight to the user here; thus, interact with the real * stdio, not the effective t_stdio, so that redirections do not get in * the way. In batch mode, a forced query is handled by writing a * message on the terminal of the parent cl (the original stderr), and * leaving some info describing the query in a file in uparm (if there is * no uparm, we abort). We then loop, waiting for the user to run "service" * in the interactive cl to service the query, leaving the answer in a * another file which we read and then delete. If we wait a long time and * get no response, we timeout. */ void query (struct param *pp) { static char *oormsg = "ERROR: Parameter value is out of range; try again"; register char *ip; char buf[SZ_PROMPTBUF+1]; struct operand o; int bastype, batch, arrflag, offset=0, n_ele, max_ele, fd; char *index(), *nlp, *nextstr(); char *bkg_query(), *query_status; char *abuf; bastype = pp->p_type & OT_BASIC; batch = firstask->t_flags & T_BATCH; arrflag = pp->p_type & PT_ARRAY; if (arrflag) { /* We may access the array many */ offset = getoffset (pp); /* times, so save the offset and */ /* push it when necessary. */ poffset (offset); max_ele = size_array (pp) - offset; } else max_ele = 1; forever { if (batch) { /* Query from a background job. */ query_status = bkg_query (buf, SZ_PROMPTBUF, pp); } else if (pp->p_type & (PT_GCUR|PT_IMCUR)) { /* Read a graphics cursor. */ char source[33]; int cursor; /* Determine the source of graphics cursor input, chosen from * either the graphics or image cursor or the terminal. */ if (pp->p_type & PT_GCUR) { if (c_envfind ("stdgcur", source, 32) <= 0) strcpy (source, "stdgraph"); } else { if (c_envfind ("stdimcur", source, 32) <= 0) strcpy (source, "stdimage"); } if (strcmp (source, "stdgraph") == 0) cursor = STDGRAPH; else if (strcmp (source, "stdimage") == 0) cursor = STDIMAGE; else goto text_query; /* get value from terminal */ /* Read a physical graphics cursor. */ pp->p_flags &= ~P_LEOF; if (cursor == STDIMAGE) { /* The following is a kludge used to temporarily implement * the logical image cursor read. In the future this will * be eliminated, and the c_rcursor call below (cursor * mode) will be used for stdimage as well as for stdgraph. * The present code (IMDRCUR) goes directly to the display * server to get the cursor value, bypassing cursor mode * and the (currently nonexistent) stdimage kernel. */ char str[SZ_LINE+1], keystr[10]; int wcs, key; float x, y; if (c_imdrcur ("stdimage", &x,&y,&wcs,&key,str,SZ_LINE, 1, 1) == EOF) { query_status = NULL; } else { if (isprint(key) && !isspace(key)) sprintf (keystr, "%c", key); else sprintf (keystr, "\\%03o", key); sprintf (buf, "%.3f %.3f %d %s %s\n", x, y, wcs, keystr, str); query_status = (char *) ((XINT) strlen(buf)); } } else if (c_rcursor (cursor, buf, SZ_PROMPTBUF) == EOF) { query_status = NULL; } else query_status = (char *) ((XINT) strlen(buf)); } else if (pp->p_type & PT_UKEY) { /* Read a user keystroke command from the terminal. */ pp->p_flags &= ~P_LEOF; if (c_rdukey (buf, SZ_PROMPTBUF) == EOF) query_status = NULL; else query_status = (char *) ((XINT) strlen(buf)); } else { text_query: fd = spf_open (buf, SZ_PROMPTBUF); pquery (pp, fdopen(fd,"a")); spf_close (fd); c_stgputline ((XINT)STDOUT, buf); if (c_stggetline ((XINT)STDIN, buf, SZ_PROMPTBUF) > 0) query_status = (char *) ((XINT) strlen(buf)); else query_status = NULL; } ip = buf; /* Set o to the current value of the parameter. Beware that some * of the logical branches which follow assume that struct o has * been initialized to the current value of the parameter. */ if (pp->p_type & PT_LIST) setopundef (&o); else if (arrflag) { paramget(pp, FN_VALUE); poffset (offset); o = popop(); } else o = pp->p_valo; /* Handle eof, a null-length line (lone carriage return), * and line with more than SZ_LINE chars. Ignore leading whitespace * if basic type is not string. */ if (query_status == NULL) { /* Typing eof will use current value (as will a lone * newline) but if param is a list, it is a meaningful * answer. */ if (pp->p_type & PT_LIST) { closelist (pp); /* close an existing file */ pp->p_flags |= P_LEOF; o = makeop (eofstr, OT_STRING); break; } goto testval; } /* Ignore leading whitespace if it is not significant for this * datatype. Do this before testing for empty line, so that a * return such as " \n" is equivalent to "\n". I.e., do not * penalize the user if they type the space bar by accident before * typing return to accept the default value. */ if (bastype != OT_STRING || (pp->p_type & (PT_FILNAM|PT_PSET))) while (*ip == ' ' || *ip == '\t') ip++; if (*ip == '\n') { /* Blank lines usually just accept the current value * but if the param is a string and is undefined, * it sets the string to a (defined) nullstring. */ *ip = '\0'; if (bastype == OT_STRING && opundef (&o)) o = makeop (ip, bastype); else goto testval; } if ((nlp = index (ip, '\n')) != NULL) *nlp = '\0'; /* cancel the newline */ else goto testval; /* Finally, we have handled the pathological cases... */ if ((pp->p_type & PT_LIST) && (!strcmp (ip,eofstr) || !strcmp (ip,"eof"))) { closelist (pp); pp->p_flags |= P_LEOF; o = makeop (eofstr, OT_STRING); break; } else { if (arrflag) { /* In querying for arrays we may set more than one * element of the array in a single query. However * we must set the first element. So we will pretend * to be a scalar until that first element is set * and then enter a loop where we may set other * elements. */ abuf = ip; ip = nextstr(&abuf, stdin); if (ip == NULL || ip == (char *) ERR || ip == undefval) goto testval; } o = makeop (ip, bastype); } testval: /* If parameter value is in range, we are done. If it is out of * range and we are a batch job or an interactive terminal job, * print an error message and request that the user enter a legal * value. If the CL is being run taking input from a file, abort, * else we will go into a loop reading illegal values from the * input file and printing out lots of error messages. */ if (inrange (pp, &o)) break; else if (batch) eprintf ("\n[%d] %s", bkgno, oormsg); else if (isatty (fileno (stdin))) eprintf ("%s\n", oormsg); else cl_error (E_UERR, oormsg); } if (!(pp->p_type & PT_LIST)) { /* update param with new value. */ if (cldebug) { eprintf ("changing `%s.p_val' to ", pp->p_name); fprop (stderr, &o); eprintf ("\n"); } pushop (&o); paramset (pp, FN_VALUE); pp->p_flags |= P_QUERY; } pushop (&o); if (arrflag && query_status != NULL && *ip != '\0') { /* If we have an array assign values until something * is used up or until we hit any error. */ n_ele = 1; forever { if (n_ele >= max_ele) /* End of array. */ break; ip = nextstr(&abuf, stdin); if (ip == NULL) /* End of query line. */ break; if (ip == (char *) ERR) { /* Error on query line. */ eprintf("Error loading array value.\n"); break; } if (ip != undefval) { o = makeop (ip, bastype); if ( ! inrange (pp, &o) ) { /* Not in range. */ eprintf("Array value outside range.\n"); break; } offset++; /* Next element in array. */ poffset (offset); pushop (&o); paramset (pp, FN_VALUE); } else offset++; n_ele++; } }
int main ( void ) /************************************************************************ * TESTSPF * * * * This program tests the CGEMLIB "SPF" library functions. * * * ** * * Log: * * J. Wu/GSC 6/01 create * * H. Zeng/SAIC 9/04 spf_read() para. list change * ***********************************************************************/ { int cont, numsub, iret, nbytes, ier, eliblen, errlen; char select[LLSCRN], filnam[LLSCRN], newfil[FILE_FULLSZ]; char ans[LLSCRN], tag[LLSCRN], data[TAGDATA_BUF]; char errlib[3], errstr[2]; long lflen; FILE *filptr; /*---------------------------------------------------------------------*/ cont = G_TRUE; filptr = NULL; strcpy( errlib, "SPF" ); strcpy( errstr, " " ); eliblen = strlen( errlib ); errlen = strlen( errstr ); while ( cont == G_TRUE ) { printf ( "\n\n" ); printf ( " ? = Print HELP file\n\n"); printf ( " D - Dump a loaded SPF file\n\n"); printf ( " 1 = SPF_CREATE 2 = SPF_OPEN 3 = SPF_READ\n" ); printf ( " 4 = SPF_LOAD 5 = SPF_WRITE 6 = SPF_GTFLD\n" ); printf ( " 7 = SPF_CLNUP 8 = SPF_CLOSE \n" ); printf ( "\n" ); printf ( "Select a subroutine number or type EXIT: " ); scanf ( " %s", select ); numsub = 0; switch ( select[0] ) { case '?': printf ("\n *** HELP FILE ***\n\n"); printf (" D - Dump a loaded SPF file\n\n"); printf (" 1 = spf_create - Create an SPF file\n" ); printf (" 2 = spf_open - Open an SPF file\n" ); printf (" 3 = spf_read - Read an opened SPF into buffer\n" ); printf (" 4 = spf_load - Load an unopened SPF into buffer\n" ); printf (" 5 = spf_write - Write a tag/data pair to an SPF\n" ); printf (" 6 = spf_gtfld - Get data field associated with a tag\n" ); printf (" 7 = spf_clnup - Clean up SPF buffer\n" ); printf (" 8 = spf_close - Close an SPF file\n" ); printf ( "\n" ); break; case 'd': case 'D': if ( _spfBuffer != (char *)NULL ) { printf ( "\n%s\n", _spfBuffer ); } else { printf ( "\nPlease load the buffer first.\n" ); } break; case 'e': case 'E': cont = G_FALSE; break; default: numsub = atoi ( select ); break; } /*---------------------------------------------------------------------*/ if ( numsub == 1 ) { if ( filptr != NULL ) { printf ( "\nPlease close the opened file first.\n" ); } else { printf ( "Enter the file name:\n" ); scanf ( " %s", filnam ); cfl_inqr( filnam, NULL, &lflen, newfil, &ier ); if ( ier != 0 ) { strcat( filnam, ".spf" ); cfl_inqr( filnam, NULL, &lflen, newfil, &ier ); } if ( ier == 0 ) { printf ( "\nCan't create, file %s already exists!\n", newfil ); } else { nbytes = (int)lflen; filptr = (FILE *)spf_create ( filnam, &nbytes, &iret ); if ( iret == 0 ) { printf ( "\nSPF_CREATE: iret = %d\n\n", iret ); } else { er_wmsg ( errlib, &iret, filnam, &ier, eliblen, strlen(filnam) ); } } } } /*---------------------------------------------------------------------*/ if ( numsub == 2 ) { if ( filptr != NULL ) { printf ( "\nPlease close the opened file first.\n" ); } else { printf ( "\nEnter the file name:\n" ); scanf ( " %s", filnam ); printf ( "Do you want to create it if the file doesn't exist?\n" ); scanf ( " %s", ans ); if ( ans[0] == 'y' || ans[0] == 'Y' ) { spf_open ( filnam, TRUE, &filptr, &nbytes, &iret ); } else { spf_open ( filnam, FALSE, &filptr, &nbytes, &iret ); } if ( iret == 0 ) { printf ( "\nSPF_OPEN: iret = %d\n\n", iret ); } else { er_wmsg ( errlib, &iret, filnam, &ier, eliblen, strlen(filnam) ); } } } /*---------------------------------------------------------------------*/ if ( numsub == 3 ) { printf ( "Enter length in bytes:\n" ); scanf ( " %d", &nbytes ); spf_read ( filptr, filnam, nbytes, &iret ); if ( iret == 0 ) { printf ( "\nSPF_READ: iret = %d\n\n", iret ); } else { er_wmsg ( errlib, &iret, errstr, &ier, eliblen, errlen ); } } /*---------------------------------------------------------------------*/ if ( numsub == 4 ) { if ( filptr != NULL ) { printf ( "\nPlease close the opened file first.\n" ); } else { printf ( "\nEnter the file name:\n" ); scanf ( " %s", filnam ); spf_load ( filnam, &iret ); if ( iret == 0 ) { printf ( "\nSPF_LOAD: iret = %d\n\n", iret ); } else { er_wmsg ( errlib, &iret, filnam, &ier, eliblen, strlen(filnam) ); } } } /*---------------------------------------------------------------------*/ if ( numsub == 5 ) { printf ( "\nEnter the tag name:\n" ); scanf ( " %s", tag ); printf ( "Enter the data string:\n" ); scanf ( " %s", data ); spf_write ( filptr, tag, data, &iret ); if ( iret == 0 ) { printf ( "\nSPF_WRITE: iret = %d\n\n", iret ); } else { er_wmsg ( errlib, &iret, errstr, &ier, eliblen, errlen ); } } /*---------------------------------------------------------------------*/ if ( numsub == 6 ) { printf ( "Enter the tag name:\n" ); scanf ( " %s", tag ); spf_gtfld ( tag, data, &iret ); if ( iret == 0 ) { printf ( "\nSPF_GTFLD: iret = %d\n\n", iret ); } else { er_wmsg ( errlib, &iret, tag, &ier, eliblen, strlen(tag) ); } printf ( "\n Tag: %s \t Data: %s\n", tag, data ); } /*---------------------------------------------------------------------*/ if ( numsub == 7 ) { spf_clnup ( &iret ); if ( iret == 0 ) { printf ( "\nSPF_CLNUP: iret = %d\n\n", iret ); } else { er_wmsg ( errlib, &iret, errstr, &ier, eliblen, errlen ); } } /*---------------------------------------------------------------------*/ if ( numsub == 8 ) { spf_close ( filptr, &iret ); filptr = NULL; if ( iret == 0 ) { printf ( "\nSPF_CLOSE: iret = %d\n\n", iret ); } else { er_wmsg ( errlib, &iret, errstr, &ier, eliblen, errlen ); } } /*---------------------------------------------------------------------*/ } if ( filptr != NULL ) fclose ( filptr ); return 0; }