
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 <stdio.h>
alpar@9: #include <stdlib.h>
alpar@9: #include <glpk.h>
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 <setjmp.h>
alpar@9: #include <stdio.h>
alpar@9: #include <stdlib.h>
alpar@9: #include <glpk.h>
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 *%




