alpar@9: %* glpk06.tex *% alpar@9: alpar@9: \chapter{Miscellaneous API Routines} alpar@9: alpar@9: \section{GLPK environment routines} alpar@9: alpar@9: \subsection{glp\_long---64-bit integer data type} alpar@9: alpar@9: Some GLPK API routines use 64-bit integer data type, which is declared alpar@9: in the header \verb|glpk.h| as follows: alpar@9: alpar@9: \begin{verbatim} alpar@9: typedef struct { int lo, hi; } glp_long; alpar@9: \end{verbatim} alpar@9: alpar@9: \noindent alpar@9: where \verb|lo| contains low 32 bits, and \verb|hi| contains high 32 alpar@9: bits of 64-bit integer value.\footnote{GLPK conforms to ILP32, LLP64, alpar@9: and LP64 programming models, where the built-in type {\tt int} alpar@9: corresponds to 32-bit integers.} alpar@9: alpar@9: \subsection{glp\_init\_env---initialize GLPK environment} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: int glp_init_env(void); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_init_env| initializes the GLPK environment. alpar@9: Normally the application program does not need to call this routine, alpar@9: because it is called automatically on the first call to any API routine. alpar@9: alpar@9: \newpage alpar@9: alpar@9: \subsubsection*{Returns} alpar@9: alpar@9: The routine \verb|glp_init_env| returns one of the following codes: alpar@9: alpar@9: \noindent alpar@9: 0 --- initialization successful; alpar@9: alpar@9: \noindent alpar@9: 1 --- environment is already initialized; alpar@9: alpar@9: \noindent alpar@9: 2 --- initialization failed (insufficient memory); alpar@9: alpar@9: \noindent alpar@9: 3 --- initialization failed (unsupported programming model). alpar@9: alpar@9: \subsection{glp\_version---determine library version} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: const char *glp_version(void); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Returns} alpar@9: alpar@9: The routine \verb|glp_version| returns a pointer to a null-terminated alpar@9: character string, which specifies the version of the GLPK library in alpar@9: the form \verb|"X.Y"|, where `\verb|X|' is the major version number, and alpar@9: `\verb|Y|' is the minor version number, for example, \verb|"4.16"|. alpar@9: alpar@9: \subsubsection*{Example} alpar@9: alpar@9: \begin{footnotesize} alpar@9: \begin{verbatim} alpar@9: printf("GLPK version is %s\n", glp_version()); alpar@9: \end{verbatim} alpar@9: \end{footnotesize} alpar@9: alpar@9: \subsection{glp\_free\_env---free GLPK environment} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: int glp_free_env(void); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_free_env| frees all resources used by GLPK alpar@9: routines (memory blocks, etc.) which are currently still in use. alpar@9: alpar@9: Normally the application program does not need to call this routine, alpar@9: because GLPK routines always free all unused resources. However, if alpar@9: the application program even has deleted all problem objects, there alpar@9: will be several memory blocks still allocated for the internal library alpar@9: needs. For some reasons the application program may want GLPK to free alpar@9: this memory, in which case it should call \verb|glp_free_env|. alpar@9: alpar@9: Note that a call to \verb|glp_free_env| invalidates all problem objects alpar@9: which still exist. alpar@9: alpar@9: \subsubsection*{Returns} alpar@9: alpar@9: The routine \verb|glp_free_env| returns one of the following codes: alpar@9: alpar@9: \noindent alpar@9: 0 --- termination successful; alpar@9: alpar@9: \noindent alpar@9: 1 --- environment is inactive (was not initialized). alpar@9: alpar@9: \subsection{glp\_printf---write formatted output to terminal} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: void glp_printf(const char *fmt, ...); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_printf| uses the format control string alpar@9: \verb|fmt| to format its parameters and writes the formatted output to alpar@9: the terminal. alpar@9: alpar@9: This routine is a replacement of the standard C function alpar@9: \verb|printf| and used by all GLPK routines to perform terminal alpar@9: output. The application program may use \verb|glp_printf| for the same alpar@9: purpose that allows controlling its terminal output with the routines alpar@9: \verb|glp_term_out| and \verb|glp_term_hook|. alpar@9: alpar@9: \subsection{glp\_vprintf---write formatted output to terminal} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: void glp_vprintf(const char *fmt, va_list arg); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_vprintf| uses the format control string alpar@9: \verb|fmt| to format its parameters specified by the list \verb|arg| alpar@9: and writes the formatted output to the terminal. alpar@9: alpar@9: This routine is a replacement of the standard C function alpar@9: \verb|vprintf| and used by all GLPK routines to perform terminal alpar@9: output. The application program may use \verb|glp_vprintf| for the same alpar@9: purpose that allows controlling its terminal output with the routines alpar@9: \verb|glp_term_out| and \verb|glp_term_hook|. alpar@9: alpar@9: \newpage alpar@9: alpar@9: \subsection{glp\_term\_out---enable/disable terminal output} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: int glp_term_out(int flag); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: Depending on the parameter flag the routine \verb|glp_term_out| enables alpar@9: or disables terminal output performed by glpk routines: alpar@9: alpar@9: \verb|GLP_ON | --- enable terminal output; alpar@9: alpar@9: \verb|GLP_OFF| --- disable terminal output. alpar@9: alpar@9: \subsubsection*{Returns} alpar@9: alpar@9: The routine \verb|glp_term_out| returns the previous value of the alpar@9: terminal output flag (\verb|GLP_ON| or \verb|GLP_OFF|). alpar@9: alpar@9: \subsection{glp\_term\_hook---intercept terminal output} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: void glp_term_hook(int (*func)(void *info, const char *s), alpar@9: void *info); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_term_hook| installs the user-defined hook routine alpar@9: to intercept all terminal output performed by GLPK routines. alpar@9: alpar@9: %This feature can be used to redirect the terminal output to other alpar@9: %destination, for example, to a file or a text window. alpar@9: alpar@9: The parameter {\it func} specifies the user-defined hook routine. It is alpar@9: called from an internal printing routine, which passes to it two alpar@9: parameters: {\it info} and {\it s}. The parameter {\it info} is a alpar@9: transit pointer specified in corresponding call to the routine alpar@9: \verb|glp_term_hook|; it may be used to pass some additional information alpar@9: to the hook routine. The parameter {\it s} is a pointer to the null alpar@9: terminated character string, which is intended to be written to the alpar@9: terminal. If the hook routine returns zero, the printing routine writes alpar@9: the string {\it s} to the terminal in a usual way; otherwise, if the alpar@9: hook routine returns non-zero, no terminal output is performed. alpar@9: alpar@9: To uninstall the hook routine both parameters {\it func} and {\it info} alpar@9: should be specified as \verb|NULL|. alpar@9: alpar@9: \newpage alpar@9: alpar@9: \subsubsection*{Example} alpar@9: alpar@9: \begin{footnotesize} alpar@9: \begin{verbatim} alpar@9: static int hook(void *info, const char *s) alpar@9: { FILE *foo = info; alpar@9: fputs(s, foo); alpar@9: return 1; alpar@9: } alpar@9: alpar@9: int main(void) alpar@9: { FILE *foo; alpar@9: . . . alpar@9: /* redirect terminal output */ alpar@9: glp_term_hook(hook, foo); alpar@9: . . . alpar@9: /* resume terminal output */ alpar@9: glp_term_hook(NULL, NULL); alpar@9: . . . alpar@9: } alpar@9: \end{verbatim} alpar@9: \end{footnotesize} alpar@9: alpar@9: \subsection{glp\_open\_tee---start copying terminal output} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: int glp_open_tee(const char *fname); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_open_tee| starts copying all the terminal output alpar@9: to an output text file, whose name is specified by the character string alpar@9: \verb|fname|. alpar@9: alpar@9: \subsubsection*{Returns} alpar@9: alpar@9: The routine \verb|glp_open_tee| returns one of the following codes: alpar@9: alpar@9: \noindent alpar@9: 0 --- operation successful; alpar@9: alpar@9: \noindent alpar@9: 1 --- copying terminal output is already active; alpar@9: alpar@9: \noindent alpar@9: 2 --- unable to create output file. alpar@9: alpar@9: \newpage alpar@9: alpar@9: \subsection{glp\_close\_tee---stop copying terminal output} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: int glp_close_tee(void); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_close_tee| stops copying the terminal output to alpar@9: the output text file previously open by the routine \verb|glp_open_tee| alpar@9: closing that file. alpar@9: alpar@9: \subsubsection*{Returns} alpar@9: alpar@9: The routine \verb|glp_close_tee| returns one of the following codes: alpar@9: alpar@9: \noindent alpar@9: 0 --- operation successful; alpar@9: alpar@9: \noindent alpar@9: 1 --- copying terminal output was not started. alpar@9: alpar@9: \subsection{glp\_error---display error message and terminate execution} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: void glp_error(const char *fmt, ...); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_error| (implemented as a macro) formats its alpar@9: parameters using the format control string \verb|fmt|, writes the alpar@9: formatted message to the terminal, and then abnormally terminates the alpar@9: program. alpar@9: alpar@9: \subsection{glp\_assert---check logical condition} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: void glp_assert(int expr); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_assert| (implemented as a macro) checks alpar@9: a logical condition specified by the expression \verb|expr|. If the alpar@9: condition is true (non-zero), the routine does nothing; otherwise, if alpar@9: the condition is false (zero), the routine prints an error message and alpar@9: abnormally terminates the program. alpar@9: alpar@9: This routine is a replacement of the standard C function \verb|assert| alpar@9: and used by all GLPK routines to check program logic. The application alpar@9: program may use \verb|glp_assert| for the same purpose. alpar@9: alpar@9: \subsection{glp\_error\_hook---install hook to intercept abnormal alpar@9: termination} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: void glp_error_hook(void (*func)(void *info), void *info); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_error_hook| installs a user-defined hook routine alpar@9: to intercept abnormal termination. alpar@9: alpar@9: The parameter \verb|func| specifies the user-defined hook routine. It alpar@9: is called from the routine \verb|glp_error| before the latter calls the alpar@9: abort function to abnormally terminate the application program because alpar@9: of fatal error. The parameter \verb|info| is a transit pointer, alpar@9: specified in the corresponding call to the routine alpar@9: \verb|glp_error_hook|; it may be used to pass some information to the alpar@9: hook routine. alpar@9: alpar@9: To uninstall the hook routine the parameters \verb|func| and \verb|info| alpar@9: should be specified as \verb|NULL|. alpar@9: alpar@9: \subsubsection*{Usage note} alpar@9: alpar@9: If the hook routine returns, the application program is abnormally alpar@9: terminated. To prevent abnormal termnation the hook routine may perform alpar@9: a global jump using the standard function \verb|longjmp|, in which case alpar@9: the application program {\it must} call the routine \verb|glp_free_env|. alpar@9: alpar@9: \subsection{glp\_malloc---allocate memory block} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: void *glp_malloc(int size); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_malloc| dynamically allocates a memory block of alpar@9: \verb|size| bytes long. Should note that: alpar@9: alpar@9: 1) the parameter \verb|size| must be positive; alpar@9: alpar@9: 2) being allocated the memory block contains arbitrary data, that is, alpar@9: it is {\it not} initialized by binary zeros; alpar@9: alpar@9: 3) if the block cannot be allocated due to insufficient memory, the alpar@9: routine prints an error message and abnormally terminates the program. alpar@9: alpar@9: This routine is a replacement of the standard C function \verb|malloc| alpar@9: and used by all GLPK routines for dynamic memory allocation. The alpar@9: application program may use \verb|glp_malloc| for the same purpose. alpar@9: alpar@9: \subsubsection*{Returns} alpar@9: alpar@9: The routine \verb|glp_malloc| returns a pointer to the memory block alpar@9: allocated. To free this block the routine \verb|glp_free| (not the alpar@9: standard C function \verb|free|!) must be used. alpar@9: alpar@9: \subsection{glp\_calloc---allocate memory block} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: void *glp_calloc(int n, int size); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_calloc| dynamically allocates a memory block of alpar@9: \verb|n|$\times$\verb|size| bytes long. Should note that: alpar@9: alpar@9: 1) both parameters \verb|n| and \verb|size| must be positive; alpar@9: alpar@9: 2) being allocated the memory block contains arbitrary data, that is, alpar@9: it is {\it not} initialized by binary zeros; alpar@9: alpar@9: 3) if the block cannot be allocated due to insufficient memory, the alpar@9: routine prints an error message and abnormally terminates the program. alpar@9: alpar@9: This routine is a replacement of the standard C function \verb|calloc| alpar@9: (with exception that the block is not cleaned) and used by all GLPK alpar@9: routines for dynamic memory allocation. The application program may use alpar@9: \verb|glp_calloc| for the same purpose. alpar@9: alpar@9: \subsubsection*{Returns} alpar@9: alpar@9: The routine \verb|glp_calloc| returns a pointer to the memory block alpar@9: allocated. To free this block the routine \verb|glp_free| (not the alpar@9: standard C function \verb|free|!) must be used. alpar@9: alpar@9: \subsection{glp\_free---free memory block} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: void glp_free(void *ptr); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_free| frees (deallocates) a memory block pointed alpar@9: to by \verb|ptr|, which was previously allocated by the routine alpar@9: \verb|glp_malloc| or \verb|glp_calloc|. Note that the pointer \verb|ptr| alpar@9: must valid and must not be \verb|NULL|. alpar@9: alpar@9: This routine is a replacement of the standard C function \verb|free| alpar@9: and used by all GLPK routines for dynamic memory allocation. The alpar@9: application program may use \verb|glp_free| for the same purpose. alpar@9: alpar@9: \subsection{glp\_mem\_usage---get memory usage information} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: void glp_mem_usage(int *count, int *cpeak, glp_long *total, alpar@9: glp_long *tpeak); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_mem_usage| reports some information about alpar@9: utilization of the memory by the routines \verb|glp_malloc|, alpar@9: \verb|glp_calloc|, and \verb|glp_free|. Information is stored to alpar@9: locations specified by corresponding parameters (see below). Any alpar@9: parameter can be specified as \verb|NULL|, in which case corresponding alpar@9: information is not stored. alpar@9: alpar@9: \verb|*count| is the number of currently allocated memory blocks. alpar@9: alpar@9: \verb|*cpeak| is the peak value of \verb|*count| reached since the alpar@9: initialization of the GLPK library environment. alpar@9: alpar@9: \verb|*total| is the total amount, in bytes, of currently allocated alpar@9: memory blocks. alpar@9: alpar@9: \verb|*tpeak| is the peak value of \verb|*total| reached since the alpar@9: initialization of the GLPK library envirionment. alpar@9: alpar@9: \subsubsection*{Example} alpar@9: alpar@9: \begin{footnotesize} alpar@9: \begin{verbatim} alpar@9: glp_mem_usage(&count, NULL, NULL, NULL); alpar@9: printf("%d memory block(s) are still allocated\n", count); alpar@9: \end{verbatim} alpar@9: \end{footnotesize} alpar@9: alpar@9: \subsection{glp\_mem\_limit---set memory usage limit} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: void glp_mem_limit(int limit); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_mem_limit| limits the amount of memory available alpar@9: for dynamic allocation (with the routines \verb|glp_malloc| and alpar@9: \verb|glp_calloc|) to \verb|limit| megabytes. alpar@9: alpar@9: \subsection{glp\_time---determine current universal time} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: glp_long glp_time(void); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsection*{Returns} alpar@9: alpar@9: The routine \verb|glp_time| returns the current universal time (UTC), alpar@9: in milliseconds, elapsed since 00:00:00 GMT January 1, 1970. alpar@9: alpar@9: \subsection{glp\_difftime---compute difference between two time values} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: double glp_difftime(glp_long t1, glp_long t0); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsection*{Returns} alpar@9: alpar@9: The routine \verb|glp_difftime| returns the difference between two time alpar@9: values \verb|t1| and \verb|t0|, expressed in seconds. alpar@9: alpar@9: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% alpar@9: alpar@9: \newpage alpar@9: alpar@9: \section{Plain data file reading routines} alpar@9: alpar@9: \subsection{Introduction} alpar@9: alpar@9: On developing simple applications to solve optimization problems it is alpar@9: often needed to read data from plain text files. To do this the standard alpar@9: C function \verb|fscanf| may be used, however, it is not convenient; for alpar@9: example, if it scans an integer number according to the format alpar@9: specification `\verb|%d|', and that number is coded incorrectly, alpar@9: no diagnostics is provided. alpar@9: alpar@9: This section describes a set of GLPK API routines, which may be used in alpar@9: application programs to simplify reading data from plain text files. alpar@9: alpar@9: \subsubsection*{Example 1} alpar@9: alpar@9: The following main program reads ten integer numbers from plain text alpar@9: file \verb|data.txt| and prints their sum. alpar@9: alpar@9: \begin{footnotesize} alpar@9: \begin{verbatim} alpar@9: /* sdfsamp1.c */ alpar@9: alpar@9: #include alpar@9: #include alpar@9: #include alpar@9: alpar@9: int main(void) alpar@9: { glp_data *data; alpar@9: int j, num, sum; alpar@9: /* open plain data file */ alpar@9: data = glp_sdf_open_file("data.txt"); alpar@9: if (data == NULL) exit(EXIT_FAILURE); alpar@9: sum = 0; alpar@9: for (j = 1; j <= 10; j++) alpar@9: { /* read next integer number */ alpar@9: num = glp_sdf_read_int(data); alpar@9: sum += num; alpar@9: } alpar@9: printf("sum = %d\n", sum); alpar@9: /* close plain data file */ alpar@9: glp_sdf_close_file(data); alpar@9: return 0; alpar@9: } alpar@9: alpar@9: /* eof */ alpar@9: \end{verbatim} alpar@9: \end{footnotesize} alpar@9: alpar@9: The input data are coded in free format. For example, the file alpar@9: \verb|data.txt| may look like this: alpar@9: alpar@9: \begin{footnotesize} alpar@9: \begin{verbatim} alpar@9: 123 65 432 890 -12 743 895 -7 111 326 alpar@9: \end{verbatim} alpar@9: \end{footnotesize} alpar@9: alpar@9: \noindent alpar@9: or like this: alpar@9: alpar@9: \begin{footnotesize} alpar@9: \begin{verbatim} alpar@9: 123 65 432 890 -12 alpar@9: 743 895 -7 111 326 alpar@9: \end{verbatim} alpar@9: \end{footnotesize} alpar@9: alpar@9: \noindent alpar@9: If the input data file contains incorrect data, the routine alpar@9: \verb|glp_sdf_read_int| prints an error message and, if no error alpar@9: handling is provided by the application program, abnormally terminates alpar@9: program execution. For example, the file \verb|data.txt| could contain alpar@9: the following data: alpar@9: alpar@9: \begin{footnotesize} alpar@9: \begin{verbatim} alpar@9: 123 65 432 890 -12 alpar@9: 743 895 =7 111 326 alpar@9: \end{verbatim} alpar@9: \end{footnotesize} alpar@9: alpar@9: \noindent alpar@9: in which case the error message would be the following: alpar@9: alpar@9: \begin{footnotesize} alpar@9: \begin{verbatim} alpar@9: data.txt:2: cannot convert `=7' to integer alpar@9: \end{verbatim} alpar@9: \end{footnotesize} alpar@9: alpar@9: \subsubsection*{Example 2} alpar@9: alpar@9: As it was said above, by default any attempt to read incorrect data alpar@9: leads to abnormal termination. However, sometimes it is desirable to alpar@9: catch such errors. This feature is illustrated by the following main alpar@9: program, which does the same job as in the previous example. alpar@9: alpar@9: \begin{footnotesize} alpar@9: \begin{verbatim} alpar@9: /* sdfsamp2.c */ alpar@9: alpar@9: #include alpar@9: #include alpar@9: #include alpar@9: #include alpar@9: alpar@9: int main(void) alpar@9: { glp_data *data; alpar@9: jmp_buf jump; alpar@9: int j, num, sum, ret; alpar@9: /* open plain data file */ alpar@9: data = glp_sdf_open_file("data.txt"); alpar@9: if (data == NULL) alpar@9: { ret = EXIT_FAILURE; alpar@9: goto done; alpar@9: } alpar@9: /* set up error handling */ alpar@9: if (setjmp(jump)) alpar@9: { ret = EXIT_FAILURE; alpar@9: goto done; alpar@9: } alpar@9: glp_sdf_set_jump(data, jump); alpar@9: /* read and process data */ alpar@9: sum = 0; alpar@9: for (j = 1; j <= 10; j++) alpar@9: { /* read next integer number */ alpar@9: num = glp_sdf_read_int(data); alpar@9: if (abs(num) > 1000) alpar@9: glp_sdf_error(data, "integer %d too big\n", num); alpar@9: if (num < 0) alpar@9: glp_sdf_warning(data, "integer %d is negative\n", num); alpar@9: sum += num; alpar@9: } alpar@9: printf("sum = %d\n", sum); alpar@9: ret = EXIT_SUCCESS; alpar@9: done: /* close plain data file */ alpar@9: if (data != NULL) glp_sdf_close_file(data); alpar@9: return ret; alpar@9: } alpar@9: alpar@9: /* eof */ alpar@9: \end{verbatim} alpar@9: \end{footnotesize} alpar@9: alpar@9: \subsection{glp\_sdf\_open\_file---open plain data file} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: glp_data *glp_sdf_open_file(const char *fname); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_sdf_open_file| opens a plain data file, whose alpar@9: name is specified by the character string \verb|fname|. alpar@9: alpar@9: \subsubsection*{Returns} alpar@9: alpar@9: If the operation was successful, the routine \verb|glp_sdf_open_file| alpar@9: returns a pointer to the opaque program object of the type alpar@9: \verb|glp_data|\footnote{This data structure is declared in the header alpar@9: file {\tt glpk.h}.} associated with the plain data file. Otherwise, if alpar@9: the operation failed, the routine prints an error message and returns alpar@9: \verb|NULL|. alpar@9: alpar@9: \subsubsection*{Note} alpar@9: alpar@9: The application program should use the pointer returned by the routine alpar@9: \verb|glp_sdf_open_file| to perform all subsequent operations on the alpar@9: data file. alpar@9: alpar@9: \newpage alpar@9: alpar@9: \subsection{glp\_sdf\_set\_jump---set up error handling} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: void glp_sdf_set_jump(glp_data *data, jmp_buf jump); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_sdf_set_jump| sets up error handling for the alpar@9: plain data file specified by the parameter \verb|data|. alpar@9: alpar@9: The parameter \verb|jump| specifies the environment buffer, which must alpar@9: be initialized with the standard C function \verb|setjmp| prior to call alpar@9: to the routine \verb|glp_sdf_set_jump|. Detecting any incorrect data in alpar@9: the corresponding plain data file will cause non-local ``go to'' by alpar@9: a call to the standard C function \verb|longjmp|. alpar@9: alpar@9: The parameter \verb|jump| can be specified as \verb|NULL|, in which alpar@9: case the routine \verb|glp_sdf_set_jump| restores the default behavior, alpar@9: in which case detecting incorrect data leads to abnormal termination. alpar@9: alpar@9: \subsection{glp\_sdf\_error---print error message} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: void glp_sdf_error(glp_data *data, const char *fmt, ...); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_sdf_error| prints an error message related to the alpar@9: plain data file specified by the parameter \verb|data|. If error handing alpar@9: was not previously provided, the routine then abnormally terminates alpar@9: execution of the application program. Otherwise, it signals about the alpar@9: error by a call to the standard C function \verb|longjmp|. alpar@9: alpar@9: The character string \verb|fmt| and optional parameters following it alpar@9: have the same meaning as for the standard C function \verb|printf|. alpar@9: alpar@9: The message produced by the routine \verb|glp_sdf_error| looks like alpar@9: follows: alpar@9: alpar@9: \medskip alpar@9: alpar@9: {\it file}{\tt :}{\it line}{\tt :} {\it message text} alpar@9: alpar@9: \medskip alpar@9: alpar@9: \noindent alpar@9: where {\it file} is the filename passed to the routine alpar@9: \verb|glp_sdf_open| and {\it line} is the current line number. alpar@9: alpar@9: \newpage alpar@9: alpar@9: \subsection{glp\_sdf\_warning---print warning message} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: void glp_sdf_warning(glp_data *data, const char *fmt, ...); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_sdf_warning| prints a warning message related to alpar@9: the plain data file specified by the parameter \verb|data|. alpar@9: alpar@9: The character string \verb|fmt| and optional parameters following it alpar@9: have the same meaning as for the standard C function \verb|printf|. alpar@9: alpar@9: The message produced by the routine \verb|glp_sdf_warning| looks like alpar@9: follows: alpar@9: alpar@9: \medskip alpar@9: alpar@9: {\it file}{\tt :}{\it line}\verb|: warning:| {\it message text} alpar@9: alpar@9: \medskip alpar@9: alpar@9: \noindent alpar@9: where {\it file} is the filename passed to the routine alpar@9: \verb|glp_sdf_open| and {\it line} is the current line number. alpar@9: alpar@9: \subsection{glp\_sdf\_read\_int---read integer number} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: int glp_sdf_read_int(glp_data *data); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_sdf_read_int| skips optional white-space alpar@9: characters and then reads an integer number from the plain data file alpar@9: specified by the parameter \verb|data|. If the operation failed, the alpar@9: routine \verb|glp_sdf_read_int| calls the routine \verb|glp_sdf_error| alpar@9: (see above). alpar@9: alpar@9: \subsubsection*{Returns} alpar@9: alpar@9: The routine \verb|glp_sdf_read_int| returns the integer number read. alpar@9: alpar@9: \newpage alpar@9: alpar@9: \subsection{glp\_sdf\_read\_num---read floating-point number} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: double glp_sdf_read_num(glp_data *data); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_sdf_read_num| skips optional white-space alpar@9: characters and then reads a floating-point number from the plain data alpar@9: file specified by the parameter \verb|data|. If the operation failed, alpar@9: the routine \verb|glp_sdf_num| calls the routine \verb|glp_sdf_error| alpar@9: (see above). alpar@9: alpar@9: \subsubsection*{Returns} alpar@9: alpar@9: The routine \verb|glp_sdf_read_num| returns the floating-point number alpar@9: read. alpar@9: alpar@9: \subsection{glp\_sdf\_read\_item---read data item} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: const char *glp_sdf_read_item(glp_data *data); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_sdf_read_item| skips optional white-space alpar@9: characters and then reads a data item from the plain data file specified alpar@9: by the parameter \verb|data|. If the operation failed, the routine alpar@9: \verb|glp_sdf_read_item| calls the routine \verb|glp_sdf_error| (see alpar@9: above). alpar@9: alpar@9: {\it Data item} is a sequence of 1 to 255 arbitrary graphic characters alpar@9: delimited by white-space characters. Data items may be used to represent alpar@9: symbolic names, identifiers, etc. alpar@9: alpar@9: \subsubsection*{Returns} alpar@9: alpar@9: The routine \verb|glp_sdf_read_item| returns a pointer to the internal alpar@9: buffer, which contains the data item read in the form of a alpar@9: null-terminated character string. alpar@9: alpar@9: \newpage alpar@9: alpar@9: \subsection{glp\_sdf\_read\_text---read text until end of line} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: const char *glp_sdf_read_text(glp_data *data); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_sdf_read_text| reads a text from the plain data alpar@9: file specified by the parameter \verb|data|. alpar@9: alpar@9: Reading starts from the current position and extends until end of the alpar@9: current line. Initial and trailing white-space characters as well as alpar@9: the newline character are not included in the text. alpar@9: alpar@9: \subsubsection*{Returns} alpar@9: alpar@9: The routine \verb|glp_sdf_read_text| returns a pointer to the internal alpar@9: buffer, which contains the text read in the form of a null-terminated alpar@9: character string. alpar@9: alpar@9: \subsection{glp\_sdf\_line---determine current line number} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: int glp_sdf_line(glp_data *data); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Returns} alpar@9: alpar@9: The routine \verb|glp_sdf_line| returns the current line number for the alpar@9: plain data file specified by the parameter \verb|data|. alpar@9: alpar@9: \subsection{glp\_sdf\_close\_file---close plain data file} alpar@9: alpar@9: \subsubsection*{Synopsis} alpar@9: alpar@9: \begin{verbatim} alpar@9: void glp_sdf_close_file(glp_data *data); alpar@9: \end{verbatim} alpar@9: alpar@9: \subsubsection*{Description} alpar@9: alpar@9: The routine \verb|glp_sdf_close_file| closes the plain data file alpar@9: specified by the parameter \verb|data| and frees all the resources alpar@9: allocated to this program object. alpar@9: alpar@9: %* eof *%