/[dtapublic]/projs/dtats/trunk/projs/2018/20180707_cgi_web_tools_aux_exe/subfunc_cfbrap.c
ViewVC logotype

Annotation of /projs/dtats/trunk/projs/2018/20180707_cgi_web_tools_aux_exe/subfunc_cfbrap.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 175 - (hide annotations) (download)
Mon Jul 9 00:00:34 2018 UTC (6 years ago) by dashley
File MIME type: text/plain
File size: 25408 byte(s)
Update license (GPL->MIT) and copyright information.  Remove CVS log, which SVN does not support.
1 dashley 172 //$Header$
2     //********************************************************************************
3 dashley 175 //Copyright (c) 2003, 2018 David T. Ashley.
4 dashley 172 //********************************************************************************
5 dashley 175 //This file is part of "arith_large_cgi", a program that is designed to be
6     //invoked by a PHP script as part of serving a web page that performs
7     //calculations involving large integers. (A secondary compiled program is
8     //used because a compiled program can perform certain calculation-intensive
9     //tasks far more efficiently than a PHP script.) This program is provided by
10     //David T. Ashley (dashley@gmail.com) under the MIT License (reproduced
11     //immediately below).
12     //********************************************************************************
13     //Permission is hereby granted, free of charge, to any person obtaining a copy
14     //of this software and associated documentation files (the "Software"), to deal
15     //in the Software without restriction, including without limitation the rights
16     //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17     //copies of the Software, and to permit persons to whom the Software is
18     //furnished to do so, subject to the following conditions:
19 dashley 172 //
20 dashley 175 //The above copyright notice and this permission notice shall be included in all
21     //copies or substantial portions of the Software.
22 dashley 172 //
23 dashley 175 //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24     //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25     //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26     //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27     //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28     //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29     //SOFTWARE.
30 dashley 172 //********************************************************************************
31     //
32     //This module finds the best rational approximations to a rational number
33     //subject to constraints on the numerator and denominator using continued
34     //fraction techniques. All of the algorithms employed are O(log N) so
35     //there should be no problem obtaining results for any practical problem.
36     //This module is based on a paper written by Dave Ashley and others providing
37     //best rational approximation algorithms.
38     //
39     //INPUT PARAMETERS
40     //----------------
41     //This subfunction accepts the following parameters, in order.
42     //
43     // (a) The numerator of the number whose best rational approximation is to
44     // be found (max 1000 digits).
45     //
46     // (b) The denominator of the number whose best rational approximation is to
47     // be found (max 1000 digits).
48     //
49     // (c) The largest allowable numerator of the approximations, or "0" if the numerator
50     // is unconstrained (max 1000 digits).
51     //
52     // (d) The largest allowable denominator of the approximations, or "0" if the denominator
53     // is unconstrained (max 1000 digits).
54     //
55     // (e) The number of neighbors to the left of the specified number to return (max 1000).
56     //
57     // (f) The number of neighbors to the right of the specified number to return (max 1000).
58     //
59     // (g) The number of significant figures to use in floating-point results (note that
60     // "significant figures" includes the numbers before the decimal point as well as
61     // after). The maximum value here is 1000.
62     //
63     // (h) The maximum number of CPU seconds to expend calculating (max 1000).
64     //
65     // NOTE (1): Numerator and denominator may not both be unconstrained.
66     //
67     //OUTPUT RESULTS
68     //--------------
69     //The notation below gives the outputs of the program. In some cases, [i] notation
70     //is used to indicate line numbers.
71     //
72     //[01] An overall success or failure code for the operation, as a string.
73     // Valid responses are:
74     // S : Success.
75     // FNPAR : The number of command-line parameters was wrong.
76     // FCPU : The operation failed because ran out of CPU time.
77     // FNUM : The operation failed because the numerator of the rational number whose
78     // neighbors are to be found was invalid or too large.
79     // FDEN : The operation failed because the denominator of the rational number whose
80     // neighbors are to be found was invalid or too large.
81     // FNUMMAX : The operation failed because the numerator limit was invalid or
82     // too large.
83     // FDENMAX : The operation failed because the denominator limit was invalid
84     // or too large.
85     // FLEFT : The operation failed because the number of left neighbors requested
86     // was invalid or too large.
87     // FRIGHT : The operation failed because the number of right neighbors requested
88     // was invalid or too large.
89     // FSIG : The number of significant figures specified was invalid.
90     // FCPU : The CPU time limit was invalid.
91     // FGEN : General failure code (catchall, if anything else is possible).
92     //
93     // For all failure codes, there will be no additional output if a failure code
94     // appears on the first line.
95     //[02] The total number of lines in the output from the program, including the start
96     // and ending lines.
97     //[03] The fully normalized numerator entered. This means it has been
98     // stripped of all weird characters, etc. This can be used by the
99     // PHP script to repopulate form boxes.
100     //[04] The fully normalized denominator entered.
101     //[05] The fully normalized maximum numerator entered.
102     //[06] The fully normalized maximum denominator entered.
103     //[07] The fully normalized number of left neighbors entered.
104     //[08] The fully normalized number of right neighbors entered.
105     //[09] The fully normalized number of significant figures requested.
106     //[10] The fully normalized number of CPU seconds allowed.
107     //
108     //The next section of the output contains the decimal form of the number that is to
109     //be approximated and also slightly more data about the number to be approximated.
110     //The PHP script may receive a number which is either specified as
111     //a rational number or as a decimal number, and the PHP script must convert it to a
112     //rational number so this program can process it. Depending on what the PHP script
113     //was given as input, it may not have the decimal form.
114     //
115     //[11] Decimal equivalent of number entered, avoiding scientific notation if
116     // possible but using it if necessary.
117     //[12] Scientific notation equivalent of number entered.
118     //[13] GCD of numerator and denominator of [04] and [05].
119     //[14] Numerator of reduced rational form.
120     //[15] Denominator of reduced rational form.
121     //
122     //This secion contains "pointers" to the major sections which may follow.
123     //All line numbers below are engineered so that "1" is the first line number
124     //in the output block and "0" represents the non-existence of the section.
125     //[16] Index to results section (code "NEIGHBORS").
126     //[17] Index to CF decomp of number to approximate (code "CFINPUT").
127     //[18] Index to CF decomp of reciprocal of number to approximate (code "CFINPUTRECIP").
128     //[19] Index to CF decomp of corner point (code "CFCORNER").
129     //[20] Index to CF decomp of reciprocal of corner point (code "CFCORNERRECIP").
130     //
131     //This section contains the neighbors of the number to approximate. The number of
132     //neighbors is strongly influenced by the number of neighbors specified on the
133     //CGI-BIN form. However, there may be fewer neighbors returned if 0/1 or the last
134     //formable rational number is encountered.
135     //[N+ 0] Constant "NEIGHBORS".
136     //[N+ 1] Number of neighbors to follow.
137     //[N+ 2] Subscript of first neighbor, from left to right. Subscripts are assigned so they rank
138     // the neighbors in relation to the number to approximate. "0" indicates that the number
139     // is the number to approximate, i.e. the number is present in the rectangular region of
140     // the integer lattice being considered.
141     //[N+ 3] 1 if the number is the corner point, or 0 otherwise.
142     //[N+ 4] Numerator of number, irreducible with respect to denominator.
143     //[N+ 5] Denominator of number, irreducible with respect to numerator.
144     //[N+ 6] Decimal form of neighbor, avoiding scientific notation if possible.
145     //[N+ 7] Decimal form of neighbor, using scientific notation.
146     //[N+ 8] Sign of error. Will be "-" for negative error or "+" otherwise.
147     //[N+ 9] Numerator of absolute value of error, irreducible with respect to denominator.
148     //[N+10] Denominator of absolute value of error, irreducible with respect to numerator.
149     //[N+11] Decimal form of absolute value of error, avoiding scientific notation if possible.
150     //[N+12] Decimal form of absolute value of error, using scientific notation.
151     //[N+13] Repeats at [N+2] for next neighbor, out to as many neighbors specified in
152     // [N+1]
153     //
154     //The next section of the output contains the continued fraction decomposition
155     //of the number to approximate.
156     //[N+ 0] Constant "CFINPUT".
157     //[N+ 1] Number of partial quotients to follow.
158     //[N+ 2] k, subscript of iteration (first subscript is 0).
159     //[N+ 3] dividend_k
160     //[N+ 4] divisor_k
161     //[N+ 5] a_k
162     //[N+ 6] remainder_k
163     //[N+ 7] p_k
164     //[N+ 8] q_k
165     //[N+ 9] k+1 ... repeats as with element [N+2] out to as many partial
166     // quotients specified in [N+1].
167     //
168     //The next section of the output contains the continued fraction decomposition
169     //of the reciprocal of the number to approximate. If the number to approximate is 0,
170     //this entire section will be omitted.
171     //[N+ 0] Constant "CFINPUTRECIP".
172     //[N+ 1] Number of partial quotients to follow.
173     //[N+ 2] k, subscript of iteration (first subscript is 0).
174     //[N+ 3] dividend_k
175     //[N+ 4] divisor_k
176     //[N+ 5] a_k
177     //[N+ 6] remainder_k
178     //[N+ 7] p_k
179     //[N+ 8] q_k
180     //[N+ 9] k+1 ... repeats as with element [N+2] out to as many partial
181     // quotients specified in [N+1].
182     //
183     //The next section of the output contains the continued fraction decomposition of the
184     //the corner point. If the numerator and denominator were not both constrained,
185     //this section will be omitted.
186     //[N+ 0] Constant "CCORNER".
187     //[N+ 1] Number of partial quotients to follow.
188     //[N+ 2] k, subscript of iteration (first subscript is 0).
189     //[N+ 3] dividend_k
190     //[N+ 4] divisor_k
191     //[N+ 5] a_k
192     //[N+ 6] remainder_k
193     //[N+ 7] p_k
194     //[N+ 8] q_k
195     //[N+ 9] k+1 ... repeats as with element [N+2] out to as many partial
196     // quotients specified in [N+1].
197     //
198     //The next section of the output contains the continued fraction decomposition of the
199     //reciprocal of the corner point. If the numerator and denominator were not both constrained,
200     //this section will be omitted.
201     //[N+ 0] Constant "CCORNERRECIP".
202     //[N+ 1] Number of partial quotients to follow.
203     //[N+ 2] k, subscript of iteration (first subscript is 0).
204     //[N+ 3] dividend_k
205     //[N+ 4] divisor_k
206     //[N+ 5] a_k
207     //[N+ 6] remainder_k
208     //[N+ 7] p_k
209     //[N+ 8] q_k
210     //[N+ 9] k+1 ... repeats as with element [N+2] out to as many partial
211     // quotients specified in [N+1].
212     //
213     //The next section is the footer.
214     //[N] Constant "S", terminator line.
215    
216     //The return value (exit code) from this subfunction is always 0.
217     //
218    
219     #define MODULE_SUBFUNC_CFBRAP
220    
221     #include <assert.h>
222     #include <ctype.h>
223     #include <stddef.h>
224     #include <stdio.h>
225     #include <stdlib.h>
226     #include <string.h>
227     #include <time.h>
228    
229     #include <gmp.h>
230    
231     #include "auxfuncs.h"
232     #include "subfunc_cfbrap.h"
233     #include "sieve_eratosthenes.h"
234    
235    
236     /****************************************************************************/
237     /* MODULE CONSTANTS */
238     /****************************************************************************/
239     #define SUBFUNC_CFBRAP_MAX_IN_DIGITS (1000)
240     //The maximum number of decimal digits that will be allowed in input rational
241     //numbers and limits.
242     #define SUBFUNC_CFBRAP_MAX_NEIGHBORS (1000)
243     //The maximum number of integer lattice rectangular region neighbors that will
244     //be allowed.
245    
246     /****************************************************************************/
247     /* MODULE DATA STRUCTURES */
248     /****************************************************************************/
249     //A structure to hold all input parameters from the command-line.
250     //
251     struct SUBFUNC_CFBRAP_input_par_struct
252     {
253     mpz_t num;
254     mpz_t den;
255     mpz_t num_max;
256     mpz_t den_max;
257     int lneighbors;
258     int rneighbors;
259     int sig_fig;
260     int max_cpu;
261     };
262    
263     //A structure to hold a single line that might be output from this
264     //program.
265     struct SUBFUNC_CFBRAP_line_buffer
266     {
267     char *line;
268     //The line itself, with zero terminator.
269     };
270    
271     //A structure to hold the collection of lines that will eventually be
272     //output from this program. These must be buffered because it is
273     //not known how many there will be.
274     //
275     struct SUBFUNC_CFBRAP_program_output_buffer
276     {
277     int nlines;
278     //The number of lines.
279     struct SUBFUNC_CFBRAP_line_buffer *lines;
280     //Pointer to the first element of array of line structures.
281     };
282    
283    
284     /****************************************************************************/
285     /* PROGRAM OUTPUT BUFFER MANIPULATION FUNCTIONS */
286     /****************************************************************************/
287     void SUBFUNC_CFBRAP_pob_init(struct SUBFUNC_CFBRAP_program_output_buffer *arg)
288     {
289     arg->nlines = 0;
290     arg->lines = NULL;
291     }
292    
293     void SUBFUNC_CFBRAP_pob_destroy(struct SUBFUNC_CFBRAP_program_output_buffer *arg)
294     {
295     int i;
296    
297     for (i=0; i<arg->nlines; i++)
298     {
299     free(arg->lines[i].line);
300     }
301    
302     if (i)
303     free(arg->lines);
304    
305     arg->nlines = 0;
306     arg->lines = NULL;
307     }
308    
309     //Tacks a line onto the output buffer.
310     //
311     void SUBFUNC_CFBRAP_pob_tack_line(struct SUBFUNC_CFBRAP_program_output_buffer *arg,
312     const char *line)
313     {
314     int tack_strlen;
315     //String length of the line to tack. Must allocate one more space for it.
316    
317     //Figure out how long the input string is.
318     tack_strlen = strlen(line);
319    
320     //If there are no lines in the buffer, allocate space for 1 else realloc.
321     if (!arg->nlines)
322     arg->lines = malloc(sizeof(struct SUBFUNC_CFBRAP_line_buffer));
323     else
324     arg->lines = realloc(arg->lines, (arg->nlines + 1) * sizeof(struct SUBFUNC_CFBRAP_line_buffer));
325    
326     //Set up for the line itself.
327     arg->lines[arg->nlines].line = malloc(tack_strlen + 1);
328    
329     //Copy in the line.
330     strcpy(arg->lines[arg->nlines].line, line);
331    
332     //We now have one more line.
333     arg->nlines++;
334     }
335    
336    
337     //Changes a line in the buffer to be something different. The first line is "1". If the line
338     //does not already exist, this function does nothing.
339     //
340     void SUBFUNC_CFBRAP_pob_modify_line(struct SUBFUNC_CFBRAP_program_output_buffer *arg,
341     int which_line,
342     const char *new_line)
343     {
344     int modify_strlen;
345     //String length of the line to swap in. Must allocate one more space for it.
346    
347     //Figure out how long the input string is.
348     modify_strlen = strlen(new_line);
349    
350     //The line number specified must be at least number 1 and the line must already
351     //exist, else do nothing.
352     if ((which_line >= 1) && (which_line <= arg->nlines))
353     {
354     //Reallocate the space to hold the new line and copy it in.
355     arg->lines[which_line-1].line = realloc(arg->lines[which_line-1].line, modify_strlen + 1);
356     strcpy(arg->lines[which_line-1].line, new_line);
357     }
358     }
359    
360    
361     //Dumps the entire output buffer to the standard output.
362     //
363     void SUBFUNC_CFBRAP_pob_dump(struct SUBFUNC_CFBRAP_program_output_buffer *arg)
364     {
365     int i;
366    
367     for (i=0; i<arg->nlines; i++)
368     {
369     printf("%s\n", arg->lines[i].line);
370     }
371     }
372    
373    
374     /****************************************************************************/
375     /* INPUT PARAMETER BLOCK MANIPULATION */
376     /****************************************************************************/
377     //Initializes the input parameter block (allocates initial storage).
378     //
379     void SUBFUNC_CFBRAP_ipblock_init(struct SUBFUNC_CFBRAP_input_par_struct *arg)
380     {
381     mpz_init(arg->num);
382     mpz_init(arg->den);
383     mpz_init(arg->num_max);
384     mpz_init(arg->den_max);
385     arg->lneighbors = 1;
386     arg->rneighbors = 1;
387     arg->sig_fig = 9;
388     arg->max_cpu = 20;
389     }
390    
391     //Deallocates the input parameter block (deallocates storage).
392     //
393     void SUBFUNC_CFBRAP_ipblock_destroy(struct SUBFUNC_CFBRAP_input_par_struct *arg)
394     {
395     mpz_clear(arg->num);
396     mpz_clear(arg->den);
397     mpz_clear(arg->num_max);
398     mpz_clear(arg->den_max);
399     arg->lneighbors = 1;
400     arg->rneighbors = 1;
401     arg->sig_fig = 9;
402     arg->max_cpu = 20;
403     }
404    
405    
406     /****************************************************************************/
407     /* ERROR PATH OUTPUT */
408     /****************************************************************************/
409     //Dumps an error code and associated proper information out to the output stream
410     //and returns.
411     //
412     int SUBFUNC_CFBRAP_error_dump(int argc, char *argv[])
413     {
414     return 0;
415     }
416    
417    
418     /****************************************************************************/
419     /* INPUT PARAMETER PARSING */
420     /****************************************************************************/
421     //Parses input parameters, stuffs the structure containing these parameters,
422     //and in the event of an error will return 1 and will stuff the output
423     //buffer with only the error code.
424     int SUBFUNC_CFBRAP_parse_input_pars(
425     int argc,
426     char *argv[],
427     struct SUBFUNC_CFBRAP_input_par_struct *ipb,
428     struct SUBFUNC_CFBRAP_program_output_buffer *pob
429     )
430     {
431     char *scratch = NULL;
432    
433     //There should be 8 input parameters in addition to the 2 required (the
434     //program name plus the subfunction code. Error out if wrong.
435     if (argc != 10)
436     {
437     SUBFUNC_CFBRAP_pob_tack_line(pob, "FNPAR");
438     return(1);
439     }
440    
441     //The first input parameter should be the numerator of the rational number to
442     //approximate. We can parse this out and place it into the input parameter
443     //block.
444     scratch = malloc(strlen(argv[2]) + 1);
445     strcpy(scratch, argv[2]);
446     AUXFUNCS_remove_non_digits(scratch);
447     AUXFUNCS_remove_leading_zeros(scratch);
448    
449     if (!strlen(scratch))
450     {
451     //The only possibility is that this was zero. Assign zero.
452     mpz_set_ui(ipb->num, 0);
453     }
454     else
455     {
456     //What is left must be a valid integer. We need to be sure it is not too
457     //long.
458     if (strlen(scratch) > SUBFUNC_CFBRAP_MAX_IN_DIGITS)
459     {
460     SUBFUNC_CFBRAP_pob_tack_line(pob, "FNUM");
461     return(1);
462     }
463     else
464     {
465     mpz_set_str(ipb->num, scratch, 10);
466     }
467     }
468    
469     //The second input parameter should be the denominator of the rational number to
470     //approximate. We can parse this out and place it into the input parameter
471     //block.
472     scratch = realloc(scratch, strlen(argv[3]) + 1);
473     strcpy(scratch, argv[3]);
474     AUXFUNCS_remove_non_digits(scratch);
475     AUXFUNCS_remove_leading_zeros(scratch);
476    
477     if (!strlen(scratch))
478     {
479     //The only possibility is that this was zero. This is a no-no.
480     SUBFUNC_CFBRAP_pob_tack_line(pob, "FDEN");
481     return(1);
482     }
483     else
484     {
485     //What is left must be a valid integer. We need to be sure it is not too
486     //long.
487     if (strlen(scratch) > SUBFUNC_CFBRAP_MAX_IN_DIGITS)
488     {
489     SUBFUNC_CFBRAP_pob_tack_line(pob, "FDEN");
490     return(1);
491     }
492     else
493     {
494     mpz_set_str(ipb->den, scratch, 10);
495     }
496     }
497    
498     //The third input parameter should be the max numerator value for approximations.
499     //We can parse this out and place it into the input parameter
500     //block.
501     scratch = malloc(strlen(argv[4]) + 1);
502     strcpy(scratch, argv[4]);
503     AUXFUNCS_remove_non_digits(scratch);
504     AUXFUNCS_remove_leading_zeros(scratch);
505    
506     if (!strlen(scratch))
507     {
508     //The only possibility is that this was zero. Assign zero.
509     mpz_set_ui(ipb->num_max, 0);
510     }
511     else
512     {
513     //What is left must be a valid integer. We need to be sure it is not too
514     //long.
515     if (strlen(scratch) > SUBFUNC_CFBRAP_MAX_IN_DIGITS)
516     {
517     SUBFUNC_CFBRAP_pob_tack_line(pob, "FNUMMAX");
518     return(1);
519     }
520     else
521     {
522     mpz_set_str(ipb->num_max, scratch, 10);
523     }
524     }
525    
526     //The fourth input parameter should be the max denominator value for approximations.
527     //We can parse this out and place it into the input parameter
528     //block.
529     scratch = malloc(strlen(argv[5]) + 1);
530     strcpy(scratch, argv[5]);
531     AUXFUNCS_remove_non_digits(scratch);
532     AUXFUNCS_remove_leading_zeros(scratch);
533    
534     if (!strlen(scratch))
535     {
536     //The only possibility is that this was zero. Assign zero.
537     mpz_set_ui(ipb->den_max, 0);
538     }
539     else
540     {
541     //What is left must be a valid integer. We need to be sure it is not too
542     //long.
543     if (strlen(scratch) > SUBFUNC_CFBRAP_MAX_IN_DIGITS)
544     {
545     SUBFUNC_CFBRAP_pob_tack_line(pob, "FDENMAX");
546     return(1);
547     }
548     else
549     {
550     mpz_set_str(ipb->den_max, scratch, 10);
551     }
552     }
553    
554     //The fifth input parameter should be the number of desired left neighbors.
555     //We can parse this out and place it into the input parameter
556     //block.
557     scratch = malloc(strlen(argv[6]) + 1);
558     strcpy(scratch, argv[6]);
559     AUXFUNCS_remove_non_digits(scratch);
560     AUXFUNCS_remove_leading_zeros(scratch);
561    
562     if (!strlen(scratch))
563     {
564     //The only possibility is that this was zero. Assign 0.
565     ipb->lneighbors = 0;
566     }
567     else
568     {
569     //What is left must be a valid integer. Scan it in.
570     //
571     if (strlen(scratch) > SUBFUNC_CFBRAP_MAX_IN_DIGITS)
572     {
573     SUBFUNC_CFBRAP_pob_tack_line(pob, "FDENMAX");
574     return(1);
575     }
576     else
577     {
578     mpz_set_str(ipb->den_max, scratch, 10);
579     }
580     }
581    
582     return(0);
583     }
584    
585    
586     /****************************************************************************/
587     /* MAIN CALCULATION FUNCTION */
588     /****************************************************************************/
589     //Carries out the best rational approximation calculation and display, knowing that
590     //all parameters have been validated.
591     //
592     int SUBFUNC_CFBRAP_calc_brap(int argc, char *argv[])
593     {
594     return 0;
595     }
596    
597    
598    
599     //Main function. Checks parameters and carries out the calculations.
600     //
601     int SUBFUNC_CFBRAP_main(int argc, char *argv[])
602     {
603     //The time snapshot against which we compare to see if we're over
604     //time budget.
605     time_t time_snapshot;
606    
607     struct SUBFUNC_CFBRAP_input_par_struct ipb;
608     //The input parameters.
609    
610     struct SUBFUNC_CFBRAP_program_output_buffer pob;
611     //The program output. Output is buffered because there are some lines
612     //early that point to later lines.
613    
614     //Scratch structure.
615     char *scratchstr = NULL;
616    
617     //Initialize the input parameter structure.
618     SUBFUNC_CFBRAP_ipblock_init(&ipb);
619    
620     //Initialize the output buffer.
621     SUBFUNC_CFBRAP_pob_init(&pob);
622    
623     //Parse, check, etc. the input parameters. If there are any issues,
624     //Jump to the end and just dump what we have.
625     if (SUBFUNC_CFBRAP_parse_input_pars(argc, argv, &ipb, &pob))
626     goto error_return;
627    
628    
629     //This is a success event. What this means is that we should store the output,
630     //which will then be send to stdout.
631     //
632     //Initial success code.
633     SUBFUNC_CFBRAP_pob_tack_line(&pob, "S");
634     //
635     //Total number of lines in the program. This is just a placeholder, until we know how
636     //many.
637     SUBFUNC_CFBRAP_pob_tack_line(&pob, "NUMLINES_PLACEHOLDER");
638     //
639     //Numerator of number to be approximated.
640     scratchstr = realloc(scratchstr, mpz_sizeinbase(ipb.num, 10) + 20);
641     gmp_sprintf(scratchstr, "%Zd", ipb.num);
642     SUBFUNC_CFBRAP_pob_tack_line(&pob, scratchstr);
643     //
644     //Denominator of number to be approximated.
645     scratchstr = realloc(scratchstr, mpz_sizeinbase(ipb.den, 10) + 20);
646     gmp_sprintf(scratchstr, "%Zd", ipb.den);
647     SUBFUNC_CFBRAP_pob_tack_line(&pob, scratchstr);
648     //
649     //Maximum numerator of approximations.
650     scratchstr = realloc(scratchstr, mpz_sizeinbase(ipb.num_max, 10) + 20);
651     gmp_sprintf(scratchstr, "%Zd", ipb.num_max);
652     SUBFUNC_CFBRAP_pob_tack_line(&pob, scratchstr);
653     //
654     //Maximum denominator of approximations.
655     scratchstr = realloc(scratchstr, mpz_sizeinbase(ipb.den_max, 10) + 20);
656     gmp_sprintf(scratchstr, "%Zd", ipb.den_max);
657     SUBFUNC_CFBRAP_pob_tack_line(&pob, scratchstr);
658     //
659     //Fill in the number of lines that we have. This replaces the placeholder.
660     {
661     char buf[100];
662    
663     sprintf(buf, "%d", pob.nlines);
664     SUBFUNC_CFBRAP_pob_modify_line(&pob, 2, buf);
665     }
666    
667    
668    
669     error_return:
670    
671     //Destroy the input parameter structure.
672     SUBFUNC_CFBRAP_ipblock_destroy(&ipb);
673    
674     //Dump the output to STDOUT.
675     SUBFUNC_CFBRAP_pob_dump(&pob);
676    
677     //Destroy the output buffer.
678     SUBFUNC_CFBRAP_pob_destroy(&pob);
679    
680     //Always return 0.
681     return(0);
682     }
683    
684     //********************************************************************************
685     // End of SUBFUNC_CFBRAP.C.
686     //********************************************************************************

Properties

Name Value
svn:eol-style native
svn:keywords Header

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25