/[dtapublic]/projs/dtats/trunk/projs/20161014_cfbrapab/c_main.c
ViewVC logotype

Annotation of /projs/dtats/trunk/projs/20161014_cfbrapab/c_main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 25 - (hide annotations) (download)
Sat Oct 8 06:43:03 2016 UTC (7 years, 5 months ago) by dashley
Original Path: sf_code/esrgpcpj/cfbrapab/c_main.c
File MIME type: text/plain
File size: 89918 byte(s)
Initial commit.
1 dashley 25 // $Header: /cvsroot/esrg/sfesrg/esrgpcpj/cfbrapab/c_main.c,v 1.6 2002/01/27 17:58:15 dtashley Exp $
2    
3     //--------------------------------------------------------------------------------
4     //Copyright 2008 David T. Ashley
5     //-------------------------------------------------------------------------------------------------
6     //This source code and any program in which it is compiled/used is provided under the GNU GENERAL
7     //PUBLIC LICENSE, Version 3, full license text below.
8     //-------------------------------------------------------------------------------------------------
9     // GNU GENERAL PUBLIC LICENSE
10     // Version 3, 29 June 2007
11     //
12     // Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
13     // Everyone is permitted to copy and distribute verbatim copies
14     // of this license document, but changing it is not allowed.
15     //
16     // Preamble
17     //
18     // The GNU General Public License is a free, copyleft license for
19     //software and other kinds of works.
20     //
21     // The licenses for most software and other practical works are designed
22     //to take away your freedom to share and change the works. By contrast,
23     //the GNU General Public License is intended to guarantee your freedom to
24     //share and change all versions of a program--to make sure it remains free
25     //software for all its users. We, the Free Software Foundation, use the
26     //GNU General Public License for most of our software; it applies also to
27     //any other work released this way by its authors. You can apply it to
28     //your programs, too.
29     //
30     // When we speak of free software, we are referring to freedom, not
31     //price. Our General Public Licenses are designed to make sure that you
32     //have the freedom to distribute copies of free software (and charge for
33     //them if you wish), that you receive source code or can get it if you
34     //want it, that you can change the software or use pieces of it in new
35     //free programs, and that you know you can do these things.
36     //
37     // To protect your rights, we need to prevent others from denying you
38     //these rights or asking you to surrender the rights. Therefore, you have
39     //certain responsibilities if you distribute copies of the software, or if
40     //you modify it: responsibilities to respect the freedom of others.
41     //
42     // For example, if you distribute copies of such a program, whether
43     //gratis or for a fee, you must pass on to the recipients the same
44     //freedoms that you received. You must make sure that they, too, receive
45     //or can get the source code. And you must show them these terms so they
46     //know their rights.
47     //
48     // Developers that use the GNU GPL protect your rights with two steps:
49     //(1) assert copyright on the software, and (2) offer you this License
50     //giving you legal permission to copy, distribute and/or modify it.
51     //
52     // For the developers' and authors' protection, the GPL clearly explains
53     //that there is no warranty for this free software. For both users' and
54     //authors' sake, the GPL requires that modified versions be marked as
55     //changed, so that their problems will not be attributed erroneously to
56     //authors of previous versions.
57     //
58     // Some devices are designed to deny users access to install or run
59     //modified versions of the software inside them, although the manufacturer
60     //can do so. This is fundamentally incompatible with the aim of
61     //protecting users' freedom to change the software. The systematic
62     //pattern of such abuse occurs in the area of products for individuals to
63     //use, which is precisely where it is most unacceptable. Therefore, we
64     //have designed this version of the GPL to prohibit the practice for those
65     //products. If such problems arise substantially in other domains, we
66     //stand ready to extend this provision to those domains in future versions
67     //of the GPL, as needed to protect the freedom of users.
68     //
69     // Finally, every program is threatened constantly by software patents.
70     //States should not allow patents to restrict development and use of
71     //software on general-purpose computers, but in those that do, we wish to
72     //avoid the special danger that patents applied to a free program could
73     //make it effectively proprietary. To prevent this, the GPL assures that
74     //patents cannot be used to render the program non-free.
75     //
76     // The precise terms and conditions for copying, distribution and
77     //modification follow.
78     //
79     // TERMS AND CONDITIONS
80     //
81     // 0. Definitions.
82     //
83     // "This License" refers to version 3 of the GNU General Public License.
84     //
85     // "Copyright" also means copyright-like laws that apply to other kinds of
86     //works, such as semiconductor masks.
87     //
88     // "The Program" refers to any copyrightable work licensed under this
89     //License. Each licensee is addressed as "you". "Licensees" and
90     //"recipients" may be individuals or organizations.
91     //
92     // To "modify" a work means to copy from or adapt all or part of the work
93     //in a fashion requiring copyright permission, other than the making of an
94     //exact copy. The resulting work is called a "modified version" of the
95     //earlier work or a work "based on" the earlier work.
96     //
97     // A "covered work" means either the unmodified Program or a work based
98     //on the Program.
99     //
100     // To "propagate" a work means to do anything with it that, without
101     //permission, would make you directly or secondarily liable for
102     //infringement under applicable copyright law, except executing it on a
103     //computer or modifying a private copy. Propagation includes copying,
104     //distribution (with or without modification), making available to the
105     //public, and in some countries other activities as well.
106     //
107     // To "convey" a work means any kind of propagation that enables other
108     //parties to make or receive copies. Mere interaction with a user through
109     //a computer network, with no transfer of a copy, is not conveying.
110     //
111     // An interactive user interface displays "Appropriate Legal Notices"
112     //to the extent that it includes a convenient and prominently visible
113     //feature that (1) displays an appropriate copyright notice, and (2)
114     //tells the user that there is no warranty for the work (except to the
115     //extent that warranties are provided), that licensees may convey the
116     //work under this License, and how to view a copy of this License. If
117     //the interface presents a list of user commands or options, such as a
118     //menu, a prominent item in the list meets this criterion.
119     //
120     // 1. Source Code.
121     //
122     // The "source code" for a work means the preferred form of the work
123     //for making modifications to it. "Object code" means any non-source
124     //form of a work.
125     //
126     // A "Standard Interface" means an interface that either is an official
127     //standard defined by a recognized standards body, or, in the case of
128     //interfaces specified for a particular programming language, one that
129     //is widely used among developers working in that language.
130     //
131     // The "System Libraries" of an executable work include anything, other
132     //than the work as a whole, that (a) is included in the normal form of
133     //packaging a Major Component, but which is not part of that Major
134     //Component, and (b) serves only to enable use of the work with that
135     //Major Component, or to implement a Standard Interface for which an
136     //implementation is available to the public in source code form. A
137     //"Major Component", in this context, means a major essential component
138     //(kernel, window system, and so on) of the specific operating system
139     //(if any) on which the executable work runs, or a compiler used to
140     //produce the work, or an object code interpreter used to run it.
141     //
142     // The "Corresponding Source" for a work in object code form means all
143     //the source code needed to generate, install, and (for an executable
144     //work) run the object code and to modify the work, including scripts to
145     //control those activities. However, it does not include the work's
146     //System Libraries, or general-purpose tools or generally available free
147     //programs which are used unmodified in performing those activities but
148     //which are not part of the work. For example, Corresponding Source
149     //includes interface definition files associated with source files for
150     //the work, and the source code for shared libraries and dynamically
151     //linked subprograms that the work is specifically designed to require,
152     //such as by intimate data communication or control flow between those
153     //subprograms and other parts of the work.
154     //
155     // The Corresponding Source need not include anything that users
156     //can regenerate automatically from other parts of the Corresponding
157     //Source.
158     //
159     // The Corresponding Source for a work in source code form is that
160     //same work.
161     //
162     // 2. Basic Permissions.
163     //
164     // All rights granted under this License are granted for the term of
165     //copyright on the Program, and are irrevocable provided the stated
166     //conditions are met. This License explicitly affirms your unlimited
167     //permission to run the unmodified Program. The output from running a
168     //covered work is covered by this License only if the output, given its
169     //content, constitutes a covered work. This License acknowledges your
170     //rights of fair use or other equivalent, as provided by copyright law.
171     //
172     // You may make, run and propagate covered works that you do not
173     //convey, without conditions so long as your license otherwise remains
174     //in force. You may convey covered works to others for the sole purpose
175     //of having them make modifications exclusively for you, or provide you
176     //with facilities for running those works, provided that you comply with
177     //the terms of this License in conveying all material for which you do
178     //not control copyright. Those thus making or running the covered works
179     //for you must do so exclusively on your behalf, under your direction
180     //and control, on terms that prohibit them from making any copies of
181     //your copyrighted material outside their relationship with you.
182     //
183     // Conveying under any other circumstances is permitted solely under
184     //the conditions stated below. Sublicensing is not allowed; section 10
185     //makes it unnecessary.
186     //
187     // 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
188     //
189     // No covered work shall be deemed part of an effective technological
190     //measure under any applicable law fulfilling obligations under article
191     //11 of the WIPO copyright treaty adopted on 20 December 1996, or
192     //similar laws prohibiting or restricting circumvention of such
193     //measures.
194     //
195     // When you convey a covered work, you waive any legal power to forbid
196     //circumvention of technological measures to the extent such circumvention
197     //is effected by exercising rights under this License with respect to
198     //the covered work, and you disclaim any intention to limit operation or
199     //modification of the work as a means of enforcing, against the work's
200     //users, your or third parties' legal rights to forbid circumvention of
201     //technological measures.
202     //
203     // 4. Conveying Verbatim Copies.
204     //
205     // You may convey verbatim copies of the Program's source code as you
206     //receive it, in any medium, provided that you conspicuously and
207     //appropriately publish on each copy an appropriate copyright notice;
208     //keep intact all notices stating that this License and any
209     //non-permissive terms added in accord with section 7 apply to the code;
210     //keep intact all notices of the absence of any warranty; and give all
211     //recipients a copy of this License along with the Program.
212     //
213     // You may charge any price or no price for each copy that you convey,
214     //and you may offer support or warranty protection for a fee.
215     //
216     // 5. Conveying Modified Source Versions.
217     //
218     // You may convey a work based on the Program, or the modifications to
219     //produce it from the Program, in the form of source code under the
220     //terms of section 4, provided that you also meet all of these conditions:
221     //
222     // a) The work must carry prominent notices stating that you modified
223     // it, and giving a relevant date.
224     //
225     // b) The work must carry prominent notices stating that it is
226     // released under this License and any conditions added under section
227     // 7. This requirement modifies the requirement in section 4 to
228     // "keep intact all notices".
229     //
230     // c) You must license the entire work, as a whole, under this
231     // License to anyone who comes into possession of a copy. This
232     // License will therefore apply, along with any applicable section 7
233     // additional terms, to the whole of the work, and all its parts,
234     // regardless of how they are packaged. This License gives no
235     // permission to license the work in any other way, but it does not
236     // invalidate such permission if you have separately received it.
237     //
238     // d) If the work has interactive user interfaces, each must display
239     // Appropriate Legal Notices; however, if the Program has interactive
240     // interfaces that do not display Appropriate Legal Notices, your
241     // work need not make them do so.
242     //
243     // A compilation of a covered work with other separate and independent
244     //works, which are not by their nature extensions of the covered work,
245     //and which are not combined with it such as to form a larger program,
246     //in or on a volume of a storage or distribution medium, is called an
247     //"aggregate" if the compilation and its resulting copyright are not
248     //used to limit the access or legal rights of the compilation's users
249     //beyond what the individual works permit. Inclusion of a covered work
250     //in an aggregate does not cause this License to apply to the other
251     //parts of the aggregate.
252     //
253     // 6. Conveying Non-Source Forms.
254     //
255     // You may convey a covered work in object code form under the terms
256     //of sections 4 and 5, provided that you also convey the
257     //machine-readable Corresponding Source under the terms of this License,
258     //in one of these ways:
259     //
260     // a) Convey the object code in, or embodied in, a physical product
261     // (including a physical distribution medium), accompanied by the
262     // Corresponding Source fixed on a durable physical medium
263     // customarily used for software interchange.
264     //
265     // b) Convey the object code in, or embodied in, a physical product
266     // (including a physical distribution medium), accompanied by a
267     // written offer, valid for at least three years and valid for as
268     // long as you offer spare parts or customer support for that product
269     // model, to give anyone who possesses the object code either (1) a
270     // copy of the Corresponding Source for all the software in the
271     // product that is covered by this License, on a durable physical
272     // medium customarily used for software interchange, for a price no
273     // more than your reasonable cost of physically performing this
274     // conveying of source, or (2) access to copy the
275     // Corresponding Source from a network server at no charge.
276     //
277     // c) Convey individual copies of the object code with a copy of the
278     // written offer to provide the Corresponding Source. This
279     // alternative is allowed only occasionally and noncommercially, and
280     // only if you received the object code with such an offer, in accord
281     // with subsection 6b.
282     //
283     // d) Convey the object code by offering access from a designated
284     // place (gratis or for a charge), and offer equivalent access to the
285     // Corresponding Source in the same way through the same place at no
286     // further charge. You need not require recipients to copy the
287     // Corresponding Source along with the object code. If the place to
288     // copy the object code is a network server, the Corresponding Source
289     // may be on a different server (operated by you or a third party)
290     // that supports equivalent copying facilities, provided you maintain
291     // clear directions next to the object code saying where to find the
292     // Corresponding Source. Regardless of what server hosts the
293     // Corresponding Source, you remain obligated to ensure that it is
294     // available for as long as needed to satisfy these requirements.
295     //
296     // e) Convey the object code using peer-to-peer transmission, provided
297     // you inform other peers where the object code and Corresponding
298     // Source of the work are being offered to the general public at no
299     // charge under subsection 6d.
300     //
301     // A separable portion of the object code, whose source code is excluded
302     //from the Corresponding Source as a System Library, need not be
303     //included in conveying the object code work.
304     //
305     // A "User Product" is either (1) a "consumer product", which means any
306     //tangible personal property which is normally used for personal, family,
307     //or household purposes, or (2) anything designed or sold for incorporation
308     //into a dwelling. In determining whether a product is a consumer product,
309     //doubtful cases shall be resolved in favor of coverage. For a particular
310     //product received by a particular user, "normally used" refers to a
311     //typical or common use of that class of product, regardless of the status
312     //of the particular user or of the way in which the particular user
313     //actually uses, or expects or is expected to use, the product. A product
314     //is a consumer product regardless of whether the product has substantial
315     //commercial, industrial or non-consumer uses, unless such uses represent
316     //the only significant mode of use of the product.
317     //
318     // "Installation Information" for a User Product means any methods,
319     //procedures, authorization keys, or other information required to install
320     //and execute modified versions of a covered work in that User Product from
321     //a modified version of its Corresponding Source. The information must
322     //suffice to ensure that the continued functioning of the modified object
323     //code is in no case prevented or interfered with solely because
324     //modification has been made.
325     //
326     // If you convey an object code work under this section in, or with, or
327     //specifically for use in, a User Product, and the conveying occurs as
328     //part of a transaction in which the right of possession and use of the
329     //User Product is transferred to the recipient in perpetuity or for a
330     //fixed term (regardless of how the transaction is characterized), the
331     //Corresponding Source conveyed under this section must be accompanied
332     //by the Installation Information. But this requirement does not apply
333     //if neither you nor any third party retains the ability to install
334     //modified object code on the User Product (for example, the work has
335     //been installed in ROM).
336     //
337     // The requirement to provide Installation Information does not include a
338     //requirement to continue to provide support service, warranty, or updates
339     //for a work that has been modified or installed by the recipient, or for
340     //the User Product in which it has been modified or installed. Access to a
341     //network may be denied when the modification itself materially and
342     //adversely affects the operation of the network or violates the rules and
343     //protocols for communication across the network.
344     //
345     // Corresponding Source conveyed, and Installation Information provided,
346     //in accord with this section must be in a format that is publicly
347     //documented (and with an implementation available to the public in
348     //source code form), and must require no special password or key for
349     //unpacking, reading or copying.
350     //
351     // 7. Additional Terms.
352     //
353     // "Additional permissions" are terms that supplement the terms of this
354     //License by making exceptions from one or more of its conditions.
355     //Additional permissions that are applicable to the entire Program shall
356     //be treated as though they were included in this License, to the extent
357     //that they are valid under applicable law. If additional permissions
358     //apply only to part of the Program, that part may be used separately
359     //under those permissions, but the entire Program remains governed by
360     //this License without regard to the additional permissions.
361     //
362     // When you convey a copy of a covered work, you may at your option
363     //remove any additional permissions from that copy, or from any part of
364     //it. (Additional permissions may be written to require their own
365     //removal in certain cases when you modify the work.) You may place
366     //additional permissions on material, added by you to a covered work,
367     //for which you have or can give appropriate copyright permission.
368     //
369     // Notwithstanding any other provision of this License, for material you
370     //add to a covered work, you may (if authorized by the copyright holders of
371     //that material) supplement the terms of this License with terms:
372     //
373     // a) Disclaiming warranty or limiting liability differently from the
374     // terms of sections 15 and 16 of this License; or
375     //
376     // b) Requiring preservation of specified reasonable legal notices or
377     // author attributions in that material or in the Appropriate Legal
378     // Notices displayed by works containing it; or
379     //
380     // c) Prohibiting misrepresentation of the origin of that material, or
381     // requiring that modified versions of such material be marked in
382     // reasonable ways as different from the original version; or
383     //
384     // d) Limiting the use for publicity purposes of names of licensors or
385     // authors of the material; or
386     //
387     // e) Declining to grant rights under trademark law for use of some
388     // trade names, trademarks, or service marks; or
389     //
390     // f) Requiring indemnification of licensors and authors of that
391     // material by anyone who conveys the material (or modified versions of
392     // it) with contractual assumptions of liability to the recipient, for
393     // any liability that these contractual assumptions directly impose on
394     // those licensors and authors.
395     //
396     // All other non-permissive additional terms are considered "further
397     //restrictions" within the meaning of section 10. If the Program as you
398     //received it, or any part of it, contains a notice stating that it is
399     //governed by this License along with a term that is a further
400     //restriction, you may remove that term. If a license document contains
401     //a further restriction but permits relicensing or conveying under this
402     //License, you may add to a covered work material governed by the terms
403     //of that license document, provided that the further restriction does
404     //not survive such relicensing or conveying.
405     //
406     // If you add terms to a covered work in accord with this section, you
407     //must place, in the relevant source files, a statement of the
408     //additional terms that apply to those files, or a notice indicating
409     //where to find the applicable terms.
410     //
411     // Additional terms, permissive or non-permissive, may be stated in the
412     //form of a separately written license, or stated as exceptions;
413     //the above requirements apply either way.
414     //
415     // 8. Termination.
416     //
417     // You may not propagate or modify a covered work except as expressly
418     //provided under this License. Any attempt otherwise to propagate or
419     //modify it is void, and will automatically terminate your rights under
420     //this License (including any patent licenses granted under the third
421     //paragraph of section 11).
422     //
423     // However, if you cease all violation of this License, then your
424     //license from a particular copyright holder is reinstated (a)
425     //provisionally, unless and until the copyright holder explicitly and
426     //finally terminates your license, and (b) permanently, if the copyright
427     //holder fails to notify you of the violation by some reasonable means
428     //prior to 60 days after the cessation.
429     //
430     // Moreover, your license from a particular copyright holder is
431     //reinstated permanently if the copyright holder notifies you of the
432     //violation by some reasonable means, this is the first time you have
433     //received notice of violation of this License (for any work) from that
434     //copyright holder, and you cure the violation prior to 30 days after
435     //your receipt of the notice.
436     //
437     // Termination of your rights under this section does not terminate the
438     //licenses of parties who have received copies or rights from you under
439     //this License. If your rights have been terminated and not permanently
440     //reinstated, you do not qualify to receive new licenses for the same
441     //material under section 10.
442     //
443     // 9. Acceptance Not Required for Having Copies.
444     //
445     // You are not required to accept this License in order to receive or
446     //run a copy of the Program. Ancillary propagation of a covered work
447     //occurring solely as a consequence of using peer-to-peer transmission
448     //to receive a copy likewise does not require acceptance. However,
449     //nothing other than this License grants you permission to propagate or
450     //modify any covered work. These actions infringe copyright if you do
451     //not accept this License. Therefore, by modifying or propagating a
452     //covered work, you indicate your acceptance of this License to do so.
453     //
454     // 10. Automatic Licensing of Downstream Recipients.
455     //
456     // Each time you convey a covered work, the recipient automatically
457     //receives a license from the original licensors, to run, modify and
458     //propagate that work, subject to this License. You are not responsible
459     //for enforcing compliance by third parties with this License.
460     //
461     // An "entity transaction" is a transaction transferring control of an
462     //organization, or substantially all assets of one, or subdividing an
463     //organization, or merging organizations. If propagation of a covered
464     //work results from an entity transaction, each party to that
465     //transaction who receives a copy of the work also receives whatever
466     //licenses to the work the party's predecessor in interest had or could
467     //give under the previous paragraph, plus a right to possession of the
468     //Corresponding Source of the work from the predecessor in interest, if
469     //the predecessor has it or can get it with reasonable efforts.
470     //
471     // You may not impose any further restrictions on the exercise of the
472     //rights granted or affirmed under this License. For example, you may
473     //not impose a license fee, royalty, or other charge for exercise of
474     //rights granted under this License, and you may not initiate litigation
475     //(including a cross-claim or counterclaim in a lawsuit) alleging that
476     //any patent claim is infringed by making, using, selling, offering for
477     //sale, or importing the Program or any portion of it.
478     //
479     // 11. Patents.
480     //
481     // A "contributor" is a copyright holder who authorizes use under this
482     //License of the Program or a work on which the Program is based. The
483     //work thus licensed is called the contributor's "contributor version".
484     //
485     // A contributor's "essential patent claims" are all patent claims
486     //owned or controlled by the contributor, whether already acquired or
487     //hereafter acquired, that would be infringed by some manner, permitted
488     //by this License, of making, using, or selling its contributor version,
489     //but do not include claims that would be infringed only as a
490     //consequence of further modification of the contributor version. For
491     //purposes of this definition, "control" includes the right to grant
492     //patent sublicenses in a manner consistent with the requirements of
493     //this License.
494     //
495     // Each contributor grants you a non-exclusive, worldwide, royalty-free
496     //patent license under the contributor's essential patent claims, to
497     //make, use, sell, offer for sale, import and otherwise run, modify and
498     //propagate the contents of its contributor version.
499     //
500     // In the following three paragraphs, a "patent license" is any express
501     //agreement or commitment, however denominated, not to enforce a patent
502     //(such as an express permission to practice a patent or covenant not to
503     //sue for patent infringement). To "grant" such a patent license to a
504     //party means to make such an agreement or commitment not to enforce a
505     //patent against the party.
506     //
507     // If you convey a covered work, knowingly relying on a patent license,
508     //and the Corresponding Source of the work is not available for anyone
509     //to copy, free of charge and under the terms of this License, through a
510     //publicly available network server or other readily accessible means,
511     //then you must either (1) cause the Corresponding Source to be so
512     //available, or (2) arrange to deprive yourself of the benefit of the
513     //patent license for this particular work, or (3) arrange, in a manner
514     //consistent with the requirements of this License, to extend the patent
515     //license to downstream recipients. "Knowingly relying" means you have
516     //actual knowledge that, but for the patent license, your conveying the
517     //covered work in a country, or your recipient's use of the covered work
518     //in a country, would infringe one or more identifiable patents in that
519     //country that you have reason to believe are valid.
520     //
521     // If, pursuant to or in connection with a single transaction or
522     //arrangement, you convey, or propagate by procuring conveyance of, a
523     //covered work, and grant a patent license to some of the parties
524     //receiving the covered work authorizing them to use, propagate, modify
525     //or convey a specific copy of the covered work, then the patent license
526     //you grant is automatically extended to all recipients of the covered
527     //work and works based on it.
528     //
529     // A patent license is "discriminatory" if it does not include within
530     //the scope of its coverage, prohibits the exercise of, or is
531     //conditioned on the non-exercise of one or more of the rights that are
532     //specifically granted under this License. You may not convey a covered
533     //work if you are a party to an arrangement with a third party that is
534     //in the business of distributing software, under which you make payment
535     //to the third party based on the extent of your activity of conveying
536     //the work, and under which the third party grants, to any of the
537     //parties who would receive the covered work from you, a discriminatory
538     //patent license (a) in connection with copies of the covered work
539     //conveyed by you (or copies made from those copies), or (b) primarily
540     //for and in connection with specific products or compilations that
541     //contain the covered work, unless you entered into that arrangement,
542     //or that patent license was granted, prior to 28 March 2007.
543     //
544     // Nothing in this License shall be construed as excluding or limiting
545     //any implied license or other defenses to infringement that may
546     //otherwise be available to you under applicable patent law.
547     //
548     // 12. No Surrender of Others' Freedom.
549     //
550     // If conditions are imposed on you (whether by court order, agreement or
551     //otherwise) that contradict the conditions of this License, they do not
552     //excuse you from the conditions of this License. If you cannot convey a
553     //covered work so as to satisfy simultaneously your obligations under this
554     //License and any other pertinent obligations, then as a consequence you may
555     //not convey it at all. For example, if you agree to terms that obligate you
556     //to collect a royalty for further conveying from those to whom you convey
557     //the Program, the only way you could satisfy both those terms and this
558     //License would be to refrain entirely from conveying the Program.
559     //
560     // 13. Use with the GNU Affero General Public License.
561     //
562     // Notwithstanding any other provision of this License, you have
563     //permission to link or combine any covered work with a work licensed
564     //under version 3 of the GNU Affero General Public License into a single
565     //combined work, and to convey the resulting work. The terms of this
566     //License will continue to apply to the part which is the covered work,
567     //but the special requirements of the GNU Affero General Public License,
568     //section 13, concerning interaction through a network will apply to the
569     //combination as such.
570     //
571     // 14. Revised Versions of this License.
572     //
573     // The Free Software Foundation may publish revised and/or new versions of
574     //the GNU General Public License from time to time. Such new versions will
575     //be similar in spirit to the present version, but may differ in detail to
576     //address new problems or concerns.
577     //
578     // Each version is given a distinguishing version number. If the
579     //Program specifies that a certain numbered version of the GNU General
580     //Public License "or any later version" applies to it, you have the
581     //option of following the terms and conditions either of that numbered
582     //version or of any later version published by the Free Software
583     //Foundation. If the Program does not specify a version number of the
584     //GNU General Public License, you may choose any version ever published
585     //by the Free Software Foundation.
586     //
587     // If the Program specifies that a proxy can decide which future
588     //versions of the GNU General Public License can be used, that proxy's
589     //public statement of acceptance of a version permanently authorizes you
590     //to choose that version for the Program.
591     //
592     // Later license versions may give you additional or different
593     //permissions. However, no additional obligations are imposed on any
594     //author or copyright holder as a result of your choosing to follow a
595     //later version.
596     //
597     // 15. Disclaimer of Warranty.
598     //
599     // THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
600     //APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
601     //HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
602     //OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
603     //THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
604     //PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
605     //IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
606     //ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
607     //
608     // 16. Limitation of Liability.
609     //
610     // IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
611     //WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
612     //THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
613     //GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
614     //USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
615     //DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
616     //PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
617     //EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
618     //SUCH DAMAGES.
619     //
620     // 17. Interpretation of Sections 15 and 16.
621     //
622     // If the disclaimer of warranty and limitation of liability provided
623     //above cannot be given local legal effect according to their terms,
624     //reviewing courts shall apply local law that most closely approximates
625     //an absolute waiver of all civil liability in connection with the
626     //Program, unless a warranty or assumption of liability accompanies a
627     //copy of the Program in return for a fee.
628     //
629     // END OF TERMS AND CONDITIONS
630     //
631     // How to Apply These Terms to Your New Programs
632     //
633     // If you develop a new program, and you want it to be of the greatest
634     //possible use to the public, the best way to achieve this is to make it
635     //free software which everyone can redistribute and change under these terms.
636     //
637     // To do so, attach the following notices to the program. It is safest
638     //to attach them to the start of each source file to most effectively
639     //state the exclusion of warranty; and each file should have at least
640     //the "copyright" line and a pointer to where the full notice is found.
641     //
642     // <one line to give the program's name and a brief idea of what it does.>
643     // Copyright (C) <year> <name of author>
644     //
645     // This program is free software: you can redistribute it and/or modify
646     // it under the terms of the GNU General Public License as published by
647     // the Free Software Foundation, either version 3 of the License, or
648     // (at your option) any later version.
649     //
650     // This program is distributed in the hope that it will be useful,
651     // but WITHOUT ANY WARRANTY; without even the implied warranty of
652     // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
653     // GNU General Public License for more details.
654     //
655     // You should have received a copy of the GNU General Public License
656     // along with this program. If not, see <http://www.gnu.org/licenses/>.
657     //
658     //Also add information on how to contact you by electronic and paper mail.
659     //
660     // If the program does terminal interaction, make it output a short
661     //notice like this when it starts in an interactive mode:
662     //
663     // <program> Copyright (C) <year> <name of author>
664     // This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
665     // This is free software, and you are welcome to redistribute it
666     // under certain conditions; type `show c' for details.
667     //
668     //The hypothetical commands `show w' and `show c' should show the appropriate
669     //parts of the General Public License. Of course, your program's commands
670     //might be different; for a GUI interface, you would use an "about box".
671     //
672     // You should also get your employer (if you work as a programmer) or school,
673     //if any, to sign a "copyright disclaimer" for the program, if necessary.
674     //For more information on this, and how to apply and follow the GNU GPL, see
675     //<http://www.gnu.org/licenses/>.
676     //
677     // The GNU General Public License does not permit incorporating your program
678     //into proprietary programs. If your program is a subroutine library, you
679     //may consider it more useful to permit linking proprietary applications with
680     //the library. If this is what you want to do, use the GNU Lesser General
681     //Public License instead of this License. But first, please read
682     //<http://www.gnu.org/philosophy/why-not-lgpl.html>.
683     //-------------------------------------------------------------------------------------------------
684     //--------------------------------------------------------------------------------
685     #include <assert.h>
686     #include <malloc.h>
687     #include <process.h>
688     #include <stdio.h>
689     #include <string.h>
690     #include <time.h>
691    
692    
693     #include "bstrfunc.h"
694     #include "ccmalloc.h"
695     #include "ccmfatal.h"
696     #include "charfunc.h"
697     #include "cu_msgs.h"
698     #include "fcmiof.h"
699     #include "gmp_ints.h"
700     #include "gmp_rats.h"
701     #include "gmp_ralg.h"
702     #include "intfunc.h"
703    
704    
705     #define PNAME "cfbrapab"
706     #define PNAMEUC "CFBRAPAB"
707    
708    
709     const char *C_MAIN_cvcinfo(void)
710     {
711     return("$Header: /cvsroot/esrg/sfesrg/esrgpcpj/cfbrapab/c_main.c,v 1.6 2002/01/27 17:58:15 dtashley Exp $");
712     }
713    
714    
715     //This is a NULL-terminated table of pointers to functions
716     //which return version control strings for all of the files
717     //which make up the INTFAC program. This information would
718     //be helpful for debugging.
719     static const char *(*C_MAIN_vcinfoptrs[])(void) =
720     {
721     //This is the main module, should come first.
722     C_MAIN_cvcinfo,
723    
724     //And now the others, in alphabetical order.
725     BSTRFUNC_hvcinfo,
726     BSTRFUNC_cvcinfo,
727     CCMALLOC_hvcinfo,
728     CCMALLOC_cvcinfo,
729     CCMFATAL_hvcinfo,
730     CCMFATAL_cvcinfo,
731     CHARFUNC_hvcinfo,
732     CHARFUNC_cvcinfo,
733     CU_MSGS_hvcinfo,
734     CU_MSGS_cvcinfo,
735     FCMIOF_hvcinfo,
736     FCMIOF_cvcinfo,
737     GMP_INTS_hvcinfo,
738     GMP_INTS_cvcinfo,
739     GMP_RALG_hvcinfo,
740     GMP_RALG_cvcinfo,
741     GMP_RATS_hvcinfo,
742     GMP_RATS_cvcinfo,
743     INTFUNC_hvcinfo,
744     INTFUNC_cvcinfo,
745     NULL
746     };
747    
748    
749     //This is the structure type used to hold information about all the
750     //command-line parameters.
751     //
752     struct CfbrapabCmainStruct
753     {
754     GMP_RATS_mpq_struct rn;
755     //The rational number specified on the command line.
756     //symmetry.
757     GMP_INTS_mpz_struct kmax;
758     //The value of KMAX specified on the command line. This must always
759     //be present.
760     int hmax_specified;
761     //TRUE if HMAX is specified in addition to KMAX. KMAX is mandatory
762     //in all cases.
763     GMP_INTS_mpz_struct hmax;
764     //The value of HMAX if it is specified. This is optional. This will be
765     //set to zero if it is not present on the command line.
766     int neversmaller_specified;
767     //TRUE if the -neversmaller option is specified on the command line.
768     int neverlarger_specified;
769     //TRUE if the -neverlarger option is specified on the command line.
770     int pred_specified;
771     //TRUE if the -pred option is specified on the command line.
772     int succ_specified;
773     //TRUE if the -succ option specified on the command line.
774     int n_specified;
775     //TRUE if the -n parameter is specified on the command line.
776     unsigned n;
777     //The value of n if it has been specified.
778     CU_MSGS_std_cmd_line_par_results_struct argblock;
779     //The block holding the options which are common across all
780     //of these command-line utilities.
781     };
782    
783    
784     //Processes the command-line parameters, and abstracts it to a
785     //the contents of a structure plus a failure flag.
786     static void process_command_line_args(struct CfbrapabCmainStruct *parblock,
787     int argc,
788     char* argv[])
789     {
790     int error_flag;
791     int first_dashed_parameter;
792     int i;
793     int recognized;
794    
795     //Eyeball the input parameters.
796     assert(parblock != NULL);
797     assert(argc >= 1);
798     assert(argv != NULL);
799    
800     //We have to have at least 3 total parameters. However, this is covered
801     //in main().
802    
803     //Process the first parameter, which has to be the rational number we
804     //want to approximate. If there is a problem, give a helpful message
805     //and exit with an error code.
806     GMP_RATS_mpq_init(&(parblock->rn));
807     GMP_RATS_mpq_set_all_format_rat_num( argv[1],
808     &error_flag,
809     &(parblock->rn));
810    
811     //If there was a parse error, announce and abort.
812     if (error_flag || GMP_RATS_mpq_is_nan(&(parblock->rn)))
813     {
814     printf("\"%s\" is not a properly formatted rational number.\n", argv[1]);
815     exit(4);
816     }
817    
818     //Normalize the rational number specified as input. It is allowed to
819     //be negative.
820     GMP_RATS_mpq_normalize(&(parblock->rn));
821    
822     //The next item has to be a number, it has to be
823     //an integer, it has to be positive, and it
824     //is KMAX. Parse out that. If there are any
825     //errors, abort.
826     GMP_INTS_mpz_init(&(parblock->kmax));
827     GMP_INTS_mpz_set_general_int(&(parblock->kmax), &error_flag, argv[2]);
828     if (error_flag || GMP_INTS_mpz_is_zero(&(parblock->kmax)) || GMP_INTS_mpz_is_neg(&(parblock->kmax)))
829     {
830     printf("\"%s\" is not a properly formatted positive integer.\n", argv[2]);
831     exit(4);
832     }
833    
834     //Unconditionally allocate space for hmax.
835     GMP_INTS_mpz_init(&(parblock->hmax));
836    
837     //If there is a third parameter, it can be two things. It can
838     //be either HMAX, or it can be the start of the parameters
839     //with dashes. First, let's decide which case applies.
840     if (argc <= 3)
841     {
842     first_dashed_parameter = 3;
843     parblock->hmax_specified = 0;
844     }
845     else
846     {
847     if (argv[3][0] == '-')
848     {
849     first_dashed_parameter = 3;
850     parblock->hmax_specified = 0;
851     }
852     else
853     {
854     first_dashed_parameter = 4;
855     parblock->hmax_specified = 1;
856    
857     GMP_INTS_mpz_set_general_int(&(parblock->hmax), &error_flag, argv[3]);
858     if (error_flag || GMP_INTS_mpz_is_zero(&(parblock->hmax)) || GMP_INTS_mpz_is_neg(&(parblock->hmax)))
859     {
860     printf("\"%s\" is not a properly formatted positive integer.\n", argv[3]);
861     exit(4);
862     }
863     }
864     }
865    
866     //Loop through the remaining parameters, trying to process each
867     //one either as a parameter specific to this program or else
868     //as a general parameter.
869     //
870     //Initialize the internal general parameter block.
871     CU_MSGS_cmd_line_par_results_struct_create(&(parblock->argblock));
872     parblock->neversmaller_specified = 0;
873     parblock->neverlarger_specified = 0;
874     parblock->pred_specified = 0;
875     parblock->succ_specified = 0;
876     parblock->n_specified = 0;
877     parblock->n = 0;
878    
879     for (i=first_dashed_parameter; i<argc; i++)
880     {
881     if (!strcmp("-neversmaller", argv[i]))
882     {
883     parblock->neversmaller_specified = 1;
884     }
885     else if (!strcmp("-neverlarger", argv[i]))
886     {
887     parblock->neverlarger_specified = 1;
888     }
889     else if (!strcmp("-pred", argv[i]))
890     {
891     parblock->pred_specified = 1;
892     }
893     else if (!strcmp("-succ", argv[i]))
894     {
895     parblock->succ_specified = 1;
896     }
897     else if (!strcmp("-n", argv[i]))
898     {
899     parblock->n_specified = 1;
900    
901     //To go along with -n, we have to have a next parameter.
902     if (i == (argc-1))
903     {
904     printf("The \"-n\" parameter must include a following count.\n");
905     exit(4);
906     }
907    
908     //Bump i to index to next par.
909     i++;
910    
911     //Try to parse this as a UINT24. It must be that.
912     GMP_INTS_mpz_parse_into_uint32(&(parblock->n), &error_flag, argv[i]);
913    
914     //If it couldn't be parsed as an integer, flunk it.
915     if (error_flag)
916     {
917     printf("\"%s\" is not a valid unsigned integer or exceeds 24 bits.\n", argv[i]);
918     exit(4);
919     }
920    
921     //If it is too large, flunk it.
922     if (parblock->n > 0x00FFFFFF)
923     {
924     printf("\"%s\" is an unsigned integer but exceeds 24 bits.\n", argv[i]);
925     exit(4);
926     }
927    
928     //OK, we're cool ...
929     }
930     else
931     {
932     //Two possibilities left. Either general parameter, or else unrecognized.
933     CU_MSGS_cmd_line_par_results_struct_process_arg(&(parblock->argblock),
934     argv[i],
935     &recognized);
936     if (!recognized)
937     {
938     printf("\"%s\" is not a recognized command-line parameter.\n", argv[i]);
939     exit(4);
940     }
941    
942     //Was picked up as general parameter.
943     }
944     }
945    
946     //Congeal our thoughts on the "general" command-line parameters. No errors possible
947     //here.
948     CU_MSGS_cmd_line_par_results_struct_finalize(&(parblock->argblock));
949    
950     //printf("Boo.\n");
951     //printf("neverlarger %d succ %d\n", parblock->neverlarger_specified, parblock->succ_specified);
952    
953     //Look for mutually exclusive options among the program-specific parameters.
954     if (
955     (parblock->neversmaller_specified && (parblock->neverlarger_specified || parblock->pred_specified || parblock->succ_specified|| parblock->n_specified))
956     ||
957     (parblock->neverlarger_specified && (parblock->pred_specified || parblock->succ_specified || parblock->n_specified))
958     ||
959     (parblock->pred_specified && (parblock->succ_specified|| parblock->n_specified))
960     ||
961     (parblock->succ_specified && parblock->n_specified)
962     )
963     {
964     printf("The \"-neversmaller\", \"-neverlarger\", \"-pred\", \"-succ\", and \"-n\" options are\nmutually exclusive.\n");
965     exit(4);
966     }
967    
968     //OK, we're clean, all pars in order.
969     }
970    
971    
972     //Releases the dynamic memory associated with the parameter block.
973     static void release_command_line_args(struct CfbrapabCmainStruct *parblock)
974     {
975     assert(parblock != NULL);
976    
977     //This function is superfluous, since in a command-line utility it doesn't really
978     //matter if everything is released. But, here goes.
979     CU_MSGS_cmd_line_par_results_struct_destroy(&(parblock->argblock));
980     GMP_RATS_mpq_clear(&(parblock->rn));
981     GMP_INTS_mpz_clear(&(parblock->kmax));
982     GMP_INTS_mpz_clear(&(parblock->hmax));
983     }
984    
985    
986     //Prints out a single rational number in the format endorsed
987     //by this program. This often includes DAP information
988     //and difference information. It is assumed that the
989     //previous information is terminated by a horizontal line,
990     //and this function terminates with a horizontal line.
991     static void CMAIN_print_app_in_std_form(FILE *s,
992     int index,
993     GMP_RATS_mpq_struct *rn,
994     GMP_RATS_mpq_struct *approx,
995     int nf,
996     int show_diff,
997     int show_dap,
998     GMP_INTS_mpz_struct *dap_den)
999     {
1000     char sbuf[250];
1001     GMP_RATS_mpq_struct diff, q_temp1;
1002     GMP_INTS_mpz_struct z_temp1, quotient, remainder;
1003    
1004     //Eyeball the input parameters.
1005     assert(s != NULL);
1006     assert(rn != NULL);
1007     assert(approx != NULL);
1008     assert(dap_den != NULL);
1009    
1010     //Allocate.
1011     GMP_RATS_mpq_init(&diff);
1012     GMP_RATS_mpq_init(&q_temp1);
1013     GMP_INTS_mpz_init(&z_temp1);
1014     GMP_INTS_mpz_init(&quotient);
1015     GMP_INTS_mpz_init(&remainder);
1016    
1017     //Print out the approximation numerator.
1018     sprintf(sbuf, "approx_num(%d)", index);
1019     if (!nf)
1020     {
1021     GMP_INTS_mpz_long_int_format_to_stream(s,
1022     &(approx->num),
1023     sbuf);
1024     }
1025     else
1026     {
1027     int nreserved;
1028     char *p;
1029    
1030     fprintf(s, "%d\n", index);
1031    
1032     nreserved = GMP_INTS_mpz_size_in_base_10(&(approx->num));
1033     p = CCMALLOC_malloc(sizeof(char) * nreserved);
1034     GMP_INTS_mpz_to_string(p, &(approx->num));
1035     fprintf(s, "%s\n", p);
1036     CCMALLOC_free(p);
1037     }
1038    
1039     if (!nf)
1040     FCMIOF_hline();
1041    
1042     //Print out the approximation denominator.
1043     sprintf(sbuf, "approx_den(%d)", index);
1044     if (!nf)
1045     {
1046     GMP_INTS_mpz_long_int_format_to_stream(s,
1047     &(approx->den),
1048     sbuf);
1049     }
1050     else
1051     {
1052     int nreserved;
1053     char *p;
1054    
1055     nreserved = GMP_INTS_mpz_size_in_base_10(&(approx->den));
1056     p = CCMALLOC_malloc(sizeof(char) * nreserved);
1057     GMP_INTS_mpz_to_string(p, &(approx->den));
1058     fprintf(s, "%s\n", p);
1059     CCMALLOC_free(p);
1060     }
1061    
1062     if (!nf)
1063     FCMIOF_hline();
1064    
1065    
1066     //If the "dap" flag is set, calculate and display decimal equivalent of the
1067     //approximation.
1068     if (show_dap)
1069     {
1070     //Make the calculation for decimal approximation.
1071     GMP_RATS_mpq_copy(&q_temp1, approx);
1072     GMP_RATS_mpq_normalize(&q_temp1);
1073     GMP_INTS_mpz_mul(&z_temp1, dap_den, &q_temp1.num);
1074     GMP_INTS_mpz_tdiv_qr(&quotient, &remainder,
1075     &z_temp1, &q_temp1.den);
1076    
1077     sprintf(sbuf, "dap_num(%d)", index);
1078     if (!nf)
1079     {
1080     GMP_INTS_mpz_long_int_format_to_stream(s,
1081     &(quotient),
1082     sbuf);
1083     }
1084     else
1085     {
1086     int nreserved;
1087     char *p;
1088    
1089     nreserved = GMP_INTS_mpz_size_in_base_10(&(quotient));
1090     p = CCMALLOC_malloc(sizeof(char) * nreserved);
1091     GMP_INTS_mpz_to_string(p, &(quotient));
1092     fprintf(s, "%s\n", p);
1093     CCMALLOC_free(p);
1094     }
1095    
1096     if (!nf)
1097     FCMIOF_hline();
1098    
1099     //Print out the approximation denominator.
1100     sprintf(sbuf, "dap_den(%d)", index);
1101     if (!nf)
1102     {
1103     GMP_INTS_mpz_long_int_format_to_stream(s,
1104     dap_den,
1105     sbuf);
1106     }
1107     else
1108     {
1109     int nreserved;
1110     char *p;
1111    
1112     nreserved = GMP_INTS_mpz_size_in_base_10(dap_den);
1113     p = CCMALLOC_malloc(sizeof(char) * nreserved);
1114     GMP_INTS_mpz_to_string(p, dap_den);
1115     fprintf(s, "%s\n", p);
1116     CCMALLOC_free(p);
1117     }
1118    
1119     if (!nf)
1120     FCMIOF_hline();
1121     }
1122    
1123    
1124     //If the "diff" flag is set, calculate and display the rational difference.
1125     if (show_diff)
1126     {
1127     GMP_RATS_mpq_sub(&diff, approx, rn);
1128     GMP_RATS_mpq_normalize(&diff);
1129    
1130     sprintf(sbuf, "error_num(%d)", index);
1131     if (!nf)
1132     {
1133     GMP_INTS_mpz_long_int_format_to_stream(s,
1134     &(diff.num),
1135     sbuf);
1136     }
1137     else
1138     {
1139     int nreserved;
1140     char *p;
1141    
1142     nreserved = GMP_INTS_mpz_size_in_base_10(&(diff.num));
1143     p = CCMALLOC_malloc(sizeof(char) * nreserved);
1144     GMP_INTS_mpz_to_string(p, &(diff.num));
1145     fprintf(s, "%s\n", p);
1146     CCMALLOC_free(p);
1147     }
1148    
1149     if (!nf)
1150     FCMIOF_hline();
1151    
1152     //Print out the approximation denominator.
1153     sprintf(sbuf, "error_den(%d)", index);
1154     if (!nf)
1155     {
1156     GMP_INTS_mpz_long_int_format_to_stream(s,
1157     &(diff.den),
1158     sbuf);
1159     }
1160     else
1161     {
1162     int nreserved;
1163     char *p;
1164    
1165     nreserved = GMP_INTS_mpz_size_in_base_10(&(diff.den));
1166     p = CCMALLOC_malloc(sizeof(char) * nreserved);
1167     GMP_INTS_mpz_to_string(p, &(diff.den));
1168     fprintf(s, "%s\n", p);
1169     CCMALLOC_free(p);
1170     }
1171    
1172     if (!nf)
1173     FCMIOF_hline();
1174     }
1175    
1176     //Deallocate.
1177     GMP_RATS_mpq_clear(&diff);
1178     GMP_RATS_mpq_clear(&q_temp1);
1179     GMP_INTS_mpz_clear(&z_temp1);
1180     GMP_INTS_mpz_clear(&quotient);
1181     GMP_INTS_mpz_clear(&remainder);
1182     }
1183    
1184    
1185     //Handles the classic case of finding the closest
1186     //neighbor(s).
1187     static int CMAIN_classic_closest_neighbor(struct CfbrapabCmainStruct *parblock)
1188     {
1189     int rv = 0;
1190     GMP_RATS_mpq_struct hmax_over_one, hmax_over_kmax, rn_in_abs;
1191     GMP_INTS_mpz_struct dap_denominator;
1192     GMP_RALG_cf_app_struct cf_decomp;
1193     GMP_RALG_fab_neighbor_collection_struct neighbor_data;
1194     int error_flag;
1195    
1196     //Allocate all dynamic memory.
1197     GMP_RATS_mpq_init(&hmax_over_one);
1198     GMP_RATS_mpq_init(&hmax_over_kmax);
1199     GMP_INTS_mpz_init(&dap_denominator);
1200     GMP_RATS_mpq_init(&rn_in_abs);
1201    
1202     //Set the DAP denominator to 1e108.
1203     GMP_INTS_mpz_set_general_int(&dap_denominator,
1204     &error_flag,
1205     "1e108");
1206    
1207     //By convention, we will not mess with anything with an
1208     //absolute value greater than HMAX/1. If such a condition exists, puke out.
1209     //Form up the value of HMAX/1 if HMAX was specified.
1210     if (parblock->hmax_specified)
1211     {
1212     GMP_INTS_mpz_copy(&(hmax_over_one.num), &(parblock->hmax));
1213     GMP_INTS_mpz_set_ui(&(hmax_over_one.den), 1);
1214     GMP_RATS_mpq_copy(&rn_in_abs, &(parblock->rn));
1215     GMP_INTS_mpz_abs(&(rn_in_abs.num));
1216     if (GMP_RATS_mpq_cmp(&(rn_in_abs), &hmax_over_one, NULL) > 0)
1217     {
1218     printf("The magnitude of the number supplied exceeds HMAX/1, and hence the number\n"
1219     "has no neighbors in the series of interest. Calculation cannot continue.\n");
1220     exit(4);
1221     }
1222     }
1223    
1224     //If the "verbose" option is specified, we want to give the continued fraction
1225     //partial quotients and convergents of either the number to approximate,
1226     //its reciprocal, or none of the above, as appropriate; and give a bit more
1227     //information, in addition.
1228     if (parblock->argblock.verbose)
1229     {
1230     if (parblock->hmax_specified)
1231     {
1232     //Stuff HMAX/KMAX. This is necessary for comparison.
1233     GMP_INTS_mpz_copy(&(hmax_over_kmax.num), &(parblock->hmax));
1234     GMP_INTS_mpz_copy(&(hmax_over_kmax.den), &(parblock->kmax));
1235     }
1236    
1237     if (!(parblock->hmax_specified) || (GMP_RATS_mpq_cmp(&(parblock->rn), &hmax_over_kmax, NULL) < 0))
1238     {
1239     //Either HMAX was not specified or else we are below the corner point on the
1240     //integer lattice. Get the continued fraction representation of the number
1241     //rather than its reciprocal.
1242     GMP_RALG_cfdecomp_init(&cf_decomp, &error_flag, &(rn_in_abs.num), &(rn_in_abs.den));
1243    
1244     //Print out the continued fraction decomposition of the rational number.
1245     GMP_RALG_cfdecomp_emit(stdout,
1246     "CF Rep Of Abs Value Of Number Specified",
1247     &cf_decomp,
1248     0,
1249     1,
1250     &dap_denominator);
1251    
1252     //Destroy the decomposition--free the memory.
1253     GMP_RALG_cfdecomp_destroy(&cf_decomp);
1254     }
1255     else if (GMP_RATS_mpq_cmp(&(rn_in_abs), &hmax_over_kmax, NULL) == 0)
1256     {
1257     //In this case, the rational number specified is exactly the same in
1258     //magnitude as HMAX/KMAX. I am inclined to suppress the CF decomp.
1259     printf("Rational number specified is HMAX/KMAX. CF decomp not provided.\n");
1260     }
1261     else
1262     {
1263     //The number specified is beyond the corner point. It is appropriate to
1264     //provide the decomposition of the reciprocal rather than of the number
1265     //itself.
1266     GMP_RALG_cfdecomp_init(&cf_decomp, &error_flag, &(rn_in_abs.den), &(rn_in_abs.num));
1267    
1268     //Print out the continued fraction decomposition of the rational number.
1269     GMP_RALG_cfdecomp_emit(stdout,
1270     "CF Rep Of Reciprocal Of Abs Value Of Number Specified",
1271     &cf_decomp,
1272     0,
1273     1,
1274     &dap_denominator);
1275    
1276     //Destroy the decomposition--free the memory.
1277     GMP_RALG_cfdecomp_destroy(&cf_decomp);
1278     }
1279     } //End if verbose.
1280    
1281     //Do all the work to get the neighbors of the number passed.
1282     GMP_RALG_consecutive_fab_terms(
1283     &(parblock->rn),
1284     &(parblock->kmax),
1285     (parblock->hmax_specified) ? (&(parblock->hmax)) : (NULL),
1286     1,
1287     1,
1288     &neighbor_data);
1289    
1290     //Print the neighbor data block for debugging.
1291     #if 0
1292     GMP_RALG_consecutive_fab_terms_result_dump(stdout, &neighbor_data);
1293     #endif
1294    
1295     //There are four possibilities at this point.
1296     // a)Attempting to find the rational neighbors generated an error.
1297     // b)The rational number specified was already in the series of interest,
1298     // in which case we will use it.
1299     // c)The left neighbor is closer or in a tie we want to choose it.
1300     // d)The right neighbor is closer or in a tie we want to choose it.
1301     if (neighbor_data.error)
1302     {
1303     //
1304     printf("Internal error: %s\n", neighbor_data.error);
1305     }
1306     else if (neighbor_data.equality)
1307     {
1308     CMAIN_print_app_in_std_form(stdout,
1309     0,
1310     &(neighbor_data.rn_in),
1311     &(neighbor_data.rn_in),
1312     parblock->argblock.noformat,
1313     0,
1314     1,
1315     &dap_denominator);
1316     }
1317     else
1318     {
1319     GMP_RATS_mpq_struct left_neighbor, right_neighbor,
1320     left_diff, right_diff,
1321     left_abs, right_abs;
1322     int error_cmp;
1323     int mag_cmp;
1324    
1325     GMP_RATS_mpq_init(&left_neighbor);
1326     GMP_RATS_mpq_init(&right_neighbor);
1327     GMP_RATS_mpq_init(&left_diff);
1328     GMP_RATS_mpq_init(&right_diff);
1329     GMP_RATS_mpq_init(&left_abs);
1330     GMP_RATS_mpq_init(&right_abs);
1331    
1332     //Snatch the left neighbor.
1333     if (neighbor_data.n_left_out)
1334     {
1335     GMP_RATS_mpq_copy(&left_neighbor, &(neighbor_data.lefts[0].neighbor));
1336     }
1337    
1338     //Snatch the right neighbor.
1339     if (neighbor_data.n_right_out)
1340     {
1341     GMP_RATS_mpq_copy(&right_neighbor, &(neighbor_data.rights[0].neighbor));
1342     }
1343    
1344     //Calculate the differences, take their absolute
1345     //values.
1346     GMP_RATS_mpq_sub(&left_diff, &left_neighbor, &(neighbor_data.rn_in));
1347     GMP_RATS_mpq_sub(&right_diff, &right_neighbor, &(neighbor_data.rn_in));
1348     GMP_RATS_mpq_normalize(&left_diff);
1349     GMP_RATS_mpq_normalize(&right_diff);
1350     GMP_INTS_mpz_abs(&(left_diff.num));
1351     GMP_INTS_mpz_abs(&(right_diff.num));
1352    
1353     //Now that the differences are calculated, take the
1354     //absolute values of the neighbors themselves.
1355     //We will use this to break ties.
1356     GMP_RATS_mpq_normalize(&left_neighbor);
1357     GMP_RATS_mpq_normalize(&right_neighbor);
1358     GMP_INTS_mpz_abs(&(left_neighbor.num));
1359     GMP_INTS_mpz_abs(&(right_neighbor.num));
1360    
1361     //Compare the relative differences and magnitudes.
1362     error_cmp = GMP_RATS_mpq_cmp(&left_diff, &right_diff, NULL);
1363     mag_cmp = GMP_RATS_mpq_cmp(&left_neighbor, &right_neighbor, NULL);
1364    
1365     //Figure out which to present as the best approximation and
1366     //do it.
1367     if (!(parblock->neversmaller_specified) &&
1368     ((parblock->neverlarger_specified) || (error_cmp < 0) || ((error_cmp == 0) && (mag_cmp < 0))))
1369     {
1370     CMAIN_print_app_in_std_form(stdout,
1371     -1,
1372     &(neighbor_data.rn_in),
1373     &(neighbor_data.lefts[0].neighbor),
1374     parblock->argblock.noformat,
1375     1,
1376     1,
1377     &dap_denominator);
1378     }
1379     else
1380     {
1381     CMAIN_print_app_in_std_form(stdout,
1382     1,
1383     &(neighbor_data.rn_in),
1384     &(neighbor_data.rights[0].neighbor),
1385     parblock->argblock.noformat,
1386     1,
1387     1,
1388     &dap_denominator);
1389     }
1390    
1391     //Deallocate.
1392     GMP_RATS_mpq_clear(&left_neighbor);
1393     GMP_RATS_mpq_clear(&right_neighbor);
1394     GMP_RATS_mpq_clear(&left_diff);
1395     GMP_RATS_mpq_clear(&right_diff);
1396     GMP_RATS_mpq_clear(&left_abs);
1397     GMP_RATS_mpq_clear(&right_abs);
1398     }
1399    
1400     //Deallocate all dynamic memory.
1401     GMP_RALG_consecutive_fab_terms_result_free(&neighbor_data);
1402     GMP_RATS_mpq_clear(&hmax_over_one);
1403     GMP_RATS_mpq_clear(&hmax_over_kmax);
1404     GMP_INTS_mpz_clear(&dap_denominator);
1405     GMP_RATS_mpq_clear(&rn_in_abs);
1406    
1407     return(rv);
1408     }
1409    
1410    
1411     //Handles the case of finding multiple neighbors.
1412    
1413     static int CMAIN_multiple_neighbor(struct CfbrapabCmainStruct *parblock)
1414     {
1415     int rv = 0;
1416     GMP_RATS_mpq_struct hmax_over_one, hmax_over_kmax, rn_in_abs;
1417     GMP_INTS_mpz_struct dap_denominator;
1418     GMP_RALG_cf_app_struct cf_decomp;
1419     GMP_RALG_fab_neighbor_collection_struct neighbor_data;
1420     int error_flag;
1421     int i;
1422    
1423     //Allocate all dynamic memory.
1424     GMP_RATS_mpq_init(&hmax_over_one);
1425     GMP_RATS_mpq_init(&hmax_over_kmax);
1426     GMP_INTS_mpz_init(&dap_denominator);
1427     GMP_RATS_mpq_init(&rn_in_abs);
1428    
1429     //Set the DAP denominator to 1e108.
1430     GMP_INTS_mpz_set_general_int(&dap_denominator,
1431     &error_flag,
1432     "1e108");
1433    
1434     //By convention, we will not mess with anything with an
1435     //absolute value greater than HMAX/1. If such a condition exists, puke out.
1436     //Form up the value of HMAX/1 if HMAX was specified.
1437     if (parblock->hmax_specified)
1438     {
1439     GMP_INTS_mpz_copy(&(hmax_over_one.num), &(parblock->hmax));
1440     GMP_INTS_mpz_set_ui(&(hmax_over_one.den), 1);
1441     GMP_RATS_mpq_copy(&rn_in_abs, &(parblock->rn));
1442     GMP_INTS_mpz_abs(&(rn_in_abs.num));
1443     if (GMP_RATS_mpq_cmp(&(rn_in_abs), &hmax_over_one, NULL) > 0)
1444     {
1445     printf("The magnitude of the number supplied exceeds HMAX/1, and hence the number\n"
1446     "has no neighbors in the series of interest. Calculation cannot continue.\n");
1447     exit(4);
1448     }
1449     }
1450    
1451     //If the "verbose" option is specified, we want to give the continued fraction
1452     //partial quotients and convergents of either the number to approximate,
1453     //its reciprocal, or none of the above, as appropriate; and give a bit more
1454     //information, in addition.
1455     if (parblock->argblock.verbose)
1456     {
1457     if (parblock->hmax_specified)
1458     {
1459     //Stuff HMAX/KMAX. This is necessary for comparison.
1460     GMP_INTS_mpz_copy(&(hmax_over_kmax.num), &(parblock->hmax));
1461     GMP_INTS_mpz_copy(&(hmax_over_kmax.den), &(parblock->kmax));
1462     }
1463    
1464     if (!(parblock->hmax_specified) || (GMP_RATS_mpq_cmp(&(parblock->rn), &hmax_over_kmax, NULL) < 0))
1465     {
1466     //Either HMAX was not specified or else we are below the corner point on the
1467     //integer lattice. Get the continued fraction representation of the number
1468     //rather than its reciprocal.
1469     GMP_RALG_cfdecomp_init(&cf_decomp, &error_flag, &(rn_in_abs.num), &(rn_in_abs.den));
1470    
1471     //Print out the continued fraction decomposition of the rational number.
1472     GMP_RALG_cfdecomp_emit(stdout,
1473     "CF Representation Of Absolute Value Of Rational Number Specified",
1474     &cf_decomp,
1475     0,
1476     1,
1477     &dap_denominator);
1478    
1479     //Destroy the decomposition--free the memory.
1480     GMP_RALG_cfdecomp_destroy(&cf_decomp);
1481     }
1482     else if (GMP_RATS_mpq_cmp(&(rn_in_abs), &hmax_over_kmax, NULL) == 0)
1483     {
1484     //In this case, the rational number specified is exactly the same in
1485     //magnitude as HMAX/KMAX. I am inclined to suppress the CF decomp.
1486     printf("Rational number specified is HMAX/KMAX. CF decomp not provided.\n");
1487     }
1488     else
1489     {
1490     //The number specified is beyond the corner point. It is appropriate to
1491     //provide the decomposition of the reciprocal rather than of the number
1492     //itself.
1493     GMP_RALG_cfdecomp_init(&cf_decomp, &error_flag, &(rn_in_abs.den), &(rn_in_abs.num));
1494    
1495     //Print out the continued fraction decomposition of the rational number.
1496     GMP_RALG_cfdecomp_emit(stdout,
1497     "CF Representation Of Reciprocal Of Absolute Value Of Rational Number Specified",
1498     &cf_decomp,
1499     0,
1500     1,
1501     &dap_denominator);
1502    
1503     //Destroy the decomposition--free the memory.
1504     GMP_RALG_cfdecomp_destroy(&cf_decomp);
1505     }
1506     } //End if verbose.
1507    
1508     //Do all the work to get the neighbors of the number passed.
1509     GMP_RALG_consecutive_fab_terms(
1510     &(parblock->rn),
1511     &(parblock->kmax),
1512     (parblock->hmax_specified) ? (&(parblock->hmax)) : (NULL),
1513     parblock->n,
1514     parblock->n,
1515     &neighbor_data);
1516    
1517     //Print the neighbor data block for debugging.
1518     #if 0
1519     GMP_RALG_consecutive_fab_terms_result_dump(stdout, &neighbor_data);
1520     #endif
1521    
1522     //Loop through, printing out the left neighbors in order.
1523     for (i = neighbor_data.n_left_out - 1; i >= 0; i--)
1524     {
1525     CMAIN_print_app_in_std_form(stdout,
1526     -(i + 1),
1527     &(neighbor_data.rn_in),
1528     &(neighbor_data.lefts[i].neighbor),
1529     parblock->argblock.noformat,
1530     1,
1531     1,
1532     &dap_denominator);
1533     }
1534    
1535     //If the number itself appears in the series of interest, spit that out.
1536     if (neighbor_data.equality)
1537     {
1538     CMAIN_print_app_in_std_form(stdout,
1539     0,
1540     &(neighbor_data.rn_in),
1541     &(neighbor_data.norm_rn),
1542     parblock->argblock.noformat,
1543     1,
1544     1,
1545     &dap_denominator);
1546     }
1547    
1548     //Loop through, printing out the right neighbors in order.
1549     for (i = 0; i < neighbor_data.n_right_out; i++)
1550     {
1551     CMAIN_print_app_in_std_form(stdout,
1552     i+1,
1553     &(neighbor_data.rn_in),
1554     &(neighbor_data.rights[i].neighbor),
1555     parblock->argblock.noformat,
1556     1,
1557     1,
1558     &dap_denominator);
1559     }
1560    
1561     //Deallocate all dynamic memory.
1562     GMP_RALG_consecutive_fab_terms_result_free(&neighbor_data);
1563     GMP_RATS_mpq_clear(&hmax_over_one);
1564     GMP_RATS_mpq_clear(&hmax_over_kmax);
1565     GMP_INTS_mpz_clear(&dap_denominator);
1566     GMP_RATS_mpq_clear(&rn_in_abs);
1567    
1568     return(rv);
1569     }
1570    
1571    
1572     //Handles the case of finding the predecessor.
1573     int CMAIN_predecessor(struct CfbrapabCmainStruct *parblock)
1574     {
1575     int rv = 0;
1576     GMP_RATS_mpq_struct hmax_over_one, hmax_over_kmax, rn_in_abs;
1577     GMP_INTS_mpz_struct dap_denominator;
1578     GMP_RALG_cf_app_struct cf_decomp;
1579     GMP_RALG_fab_neighbor_collection_struct neighbor_data;
1580     int error_flag;
1581    
1582     //Allocate all dynamic memory.
1583     GMP_RATS_mpq_init(&hmax_over_one);
1584     GMP_RATS_mpq_init(&hmax_over_kmax);
1585     GMP_INTS_mpz_init(&dap_denominator);
1586     GMP_RATS_mpq_init(&rn_in_abs);
1587    
1588     //Set the DAP denominator to 1e108.
1589     GMP_INTS_mpz_set_general_int(&dap_denominator,
1590     &error_flag,
1591     "1e108");
1592    
1593     //By convention, we will not mess with anything with an
1594     //absolute value greater than HMAX/1. If such a condition exists, puke out.
1595     //Form up the value of HMAX/1 if HMAX was specified.
1596     if (parblock->hmax_specified)
1597     {
1598     GMP_INTS_mpz_copy(&(hmax_over_one.num), &(parblock->hmax));
1599     GMP_INTS_mpz_set_ui(&(hmax_over_one.den), 1);
1600     GMP_RATS_mpq_copy(&rn_in_abs, &(parblock->rn));
1601     GMP_INTS_mpz_abs(&(rn_in_abs.num));
1602     if (GMP_RATS_mpq_cmp(&(rn_in_abs), &hmax_over_one, NULL) > 0)
1603     {
1604     printf("The magnitude of the number supplied exceeds HMAX/1, and hence the number\n"
1605     "has no neighbors in the series of interest. Calculation cannot continue.\n");
1606     exit(4);
1607     }
1608     }
1609    
1610     //If the "verbose" option is specified, we want to give the continued fraction
1611     //partial quotients and convergents of either the number to approximate,
1612     //its reciprocal, or none of the above, as appropriate; and give a bit more
1613     //information, in addition.
1614     if (parblock->argblock.verbose)
1615     {
1616     if (parblock->hmax_specified)
1617     {
1618     //Stuff HMAX/KMAX. This is necessary for comparison.
1619     GMP_INTS_mpz_copy(&(hmax_over_kmax.num), &(parblock->hmax));
1620     GMP_INTS_mpz_copy(&(hmax_over_kmax.den), &(parblock->kmax));
1621     }
1622    
1623     if (!(parblock->hmax_specified) || (GMP_RATS_mpq_cmp(&(parblock->rn), &hmax_over_kmax, NULL) < 0))
1624     {
1625     //Either HMAX was not specified or else we are below the corner point on the
1626     //integer lattice. Get the continued fraction representation of the number
1627     //rather than its reciprocal.
1628     GMP_RALG_cfdecomp_init(&cf_decomp, &error_flag, &(rn_in_abs.num), &(rn_in_abs.den));
1629    
1630     //Print out the continued fraction decomposition of the rational number.
1631     GMP_RALG_cfdecomp_emit(stdout,
1632     "CF Representation Of Absolute Value Of Rational Number Specified",
1633     &cf_decomp,
1634     0,
1635     1,
1636     &dap_denominator);
1637    
1638     //Destroy the decomposition--free the memory.
1639     GMP_RALG_cfdecomp_destroy(&cf_decomp);
1640     }
1641     else if (GMP_RATS_mpq_cmp(&(rn_in_abs), &hmax_over_kmax, NULL) == 0)
1642     {
1643     //In this case, the rational number specified is exactly the same in
1644     //magnitude as HMAX/KMAX. I am inclined to suppress the CF decomp.
1645     printf("Rational number specified is HMAX/KMAX. CF decomp not provided.\n");
1646     }
1647     else
1648     {
1649     //The number specified is beyond the corner point. It is appropriate to
1650     //provide the decomposition of the reciprocal rather than of the number
1651     //itself.
1652     GMP_RALG_cfdecomp_init(&cf_decomp, &error_flag, &(rn_in_abs.den), &(rn_in_abs.num));
1653    
1654     //Print out the continued fraction decomposition of the rational number.
1655     GMP_RALG_cfdecomp_emit(stdout,
1656     "CF Representation Of Reciprocal Of Absolute Value Of Rational Number Specified",
1657     &cf_decomp,
1658     0,
1659     1,
1660     &dap_denominator);
1661    
1662     //Destroy the decomposition--free the memory.
1663     GMP_RALG_cfdecomp_destroy(&cf_decomp);
1664     }
1665     } //End if verbose.
1666    
1667     //Do all the work to get the neighbors of the number passed.
1668     GMP_RALG_consecutive_fab_terms(
1669     &(parblock->rn),
1670     &(parblock->kmax),
1671     (parblock->hmax_specified) ? (&(parblock->hmax)) : (NULL),
1672     1,
1673     0,
1674     &neighbor_data);
1675    
1676     //Print the neighbor data block for debugging.
1677     #if 0
1678     GMP_RALG_consecutive_fab_terms_result_dump(stdout, &neighbor_data);
1679     #endif
1680    
1681     //Print the neighbor on the left, if it exists.
1682     if (neighbor_data.n_left_out)
1683     {
1684     CMAIN_print_app_in_std_form(stdout,
1685     -1,
1686     &(neighbor_data.rn_in),
1687     &(neighbor_data.lefts[0].neighbor),
1688     parblock->argblock.noformat,
1689     0,
1690     0,
1691     &dap_denominator);
1692     }
1693    
1694     //Deallocate all dynamic memory.
1695     GMP_RALG_consecutive_fab_terms_result_free(&neighbor_data);
1696     GMP_RATS_mpq_clear(&hmax_over_one);
1697     GMP_RATS_mpq_clear(&hmax_over_kmax);
1698     GMP_INTS_mpz_clear(&dap_denominator);
1699     GMP_RATS_mpq_clear(&rn_in_abs);
1700    
1701     return(rv);
1702     }
1703    
1704    
1705     //Handles the case of finding the successor.
1706     int CMAIN_successor(struct CfbrapabCmainStruct *parblock)
1707     {
1708     int rv = 0;
1709     GMP_RATS_mpq_struct hmax_over_one, hmax_over_kmax, rn_in_abs;
1710     GMP_INTS_mpz_struct dap_denominator;
1711     GMP_RALG_cf_app_struct cf_decomp;
1712     GMP_RALG_fab_neighbor_collection_struct neighbor_data;
1713     int error_flag;
1714    
1715     //Allocate all dynamic memory.
1716     GMP_RATS_mpq_init(&hmax_over_one);
1717     GMP_RATS_mpq_init(&hmax_over_kmax);
1718     GMP_INTS_mpz_init(&dap_denominator);
1719     GMP_RATS_mpq_init(&rn_in_abs);
1720    
1721     //Set the DAP denominator to 1e108.
1722     GMP_INTS_mpz_set_general_int(&dap_denominator,
1723     &error_flag,
1724     "1e108");
1725    
1726     //By convention, we will not mess with anything with an
1727     //absolute value greater than HMAX/1. If such a condition exists, puke out.
1728     //Form up the value of HMAX/1 if HMAX was specified.
1729     if (parblock->hmax_specified)
1730     {
1731     GMP_INTS_mpz_copy(&(hmax_over_one.num), &(parblock->hmax));
1732     GMP_INTS_mpz_set_ui(&(hmax_over_one.den), 1);
1733     GMP_RATS_mpq_copy(&rn_in_abs, &(parblock->rn));
1734     GMP_INTS_mpz_abs(&(rn_in_abs.num));
1735     if (GMP_RATS_mpq_cmp(&(rn_in_abs), &hmax_over_one, NULL) > 0)
1736     {
1737     printf("The magnitude of the number supplied exceeds HMAX/1, and hence the number\n"
1738     "has no neighbors in the series of interest. Calculation cannot continue.\n");
1739     exit(4);
1740     }
1741     }
1742    
1743     //If the "verbose" option is specified, we want to give the continued fraction
1744     //partial quotients and convergents of either the number to approximate,
1745     //its reciprocal, or none of the above, as appropriate; and give a bit more
1746     //information, in addition.
1747     if (parblock->argblock.verbose)
1748     {
1749     if (parblock->hmax_specified)
1750     {
1751     //Stuff HMAX/KMAX. This is necessary for comparison.
1752     GMP_INTS_mpz_copy(&(hmax_over_kmax.num), &(parblock->hmax));
1753     GMP_INTS_mpz_copy(&(hmax_over_kmax.den), &(parblock->kmax));
1754     }
1755    
1756     if (!(parblock->hmax_specified) || (GMP_RATS_mpq_cmp(&(parblock->rn), &hmax_over_kmax, NULL) < 0))
1757     {
1758     //Either HMAX was not specified or else we are below the corner point on the
1759     //integer lattice. Get the continued fraction representation of the number
1760     //rather than its reciprocal.
1761     GMP_RALG_cfdecomp_init(&cf_decomp, &error_flag, &(rn_in_abs.num), &(rn_in_abs.den));
1762    
1763     //Print out the continued fraction decomposition of the rational number.
1764     GMP_RALG_cfdecomp_emit(stdout,
1765     "CF Representation Of Absolute Value Of Rational Number Specified",
1766     &cf_decomp,
1767     0,
1768     1,
1769     &dap_denominator);
1770    
1771     //Destroy the decomposition--free the memory.
1772     GMP_RALG_cfdecomp_destroy(&cf_decomp);
1773     }
1774     else if (GMP_RATS_mpq_cmp(&(rn_in_abs), &hmax_over_kmax, NULL) == 0)
1775     {
1776     //In this case, the rational number specified is exactly the same in
1777     //magnitude as HMAX/KMAX. I am inclined to suppress the CF decomp.
1778     printf("Rational number specified is HMAX/KMAX. CF decomp not provided.\n");
1779     }
1780     else
1781     {
1782     //The number specified is beyond the corner point. It is appropriate to
1783     //provide the decomposition of the reciprocal rather than of the number
1784     //itself.
1785     GMP_RALG_cfdecomp_init(&cf_decomp, &error_flag, &(rn_in_abs.den), &(rn_in_abs.num));
1786    
1787     //Print out the continued fraction decomposition of the rational number.
1788     GMP_RALG_cfdecomp_emit(stdout,
1789     "CF Representation Of Reciprocal Of Absolute Value Of Rational Number Specified",
1790     &cf_decomp,
1791     0,
1792     1,
1793     &dap_denominator);
1794    
1795     //Destroy the decomposition--free the memory.
1796     GMP_RALG_cfdecomp_destroy(&cf_decomp);
1797     }
1798     } //End if verbose.
1799    
1800     //Do all the work to get the neighbors of the number passed.
1801     GMP_RALG_consecutive_fab_terms(
1802     &(parblock->rn),
1803     &(parblock->kmax),
1804     (parblock->hmax_specified) ? (&(parblock->hmax)) : (NULL),
1805     0,
1806     1,
1807     &neighbor_data);
1808    
1809     //Print the neighbor data block for debugging.
1810     #if 0
1811     GMP_RALG_consecutive_fab_terms_result_dump(stdout, &neighbor_data);
1812     #endif
1813    
1814     //Print the neighbor on the right, if it exists.
1815     if (neighbor_data.n_right_out)
1816     {
1817     CMAIN_print_app_in_std_form(stdout,
1818     -1,
1819     &(neighbor_data.rn_in),
1820     &(neighbor_data.rights[0].neighbor),
1821     parblock->argblock.noformat,
1822     0,
1823     0,
1824     &dap_denominator);
1825     }
1826    
1827     //Deallocate all dynamic memory.
1828     GMP_RALG_consecutive_fab_terms_result_free(&neighbor_data);
1829     GMP_RATS_mpq_clear(&hmax_over_one);
1830     GMP_RATS_mpq_clear(&hmax_over_kmax);
1831     GMP_INTS_mpz_clear(&dap_denominator);
1832     GMP_RATS_mpq_clear(&rn_in_abs);
1833    
1834     return(rv);
1835     }
1836    
1837    
1838     int c_main(int argc, char* argv[])
1839     {
1840     int rv=0;
1841     struct CfbrapabCmainStruct parblock;
1842    
1843     if (argc==2 && !strcmp(argv[1], "-help"))
1844     {
1845     FCMIOF_hline();
1846     printf("DESCRIPTION\n");
1847     printf(" This utility calculates best rational approximations of the form h/k\n");
1848     printf(" under the constraint k <= KMAX (i.e. in the Farey series of order KMAX),\n");
1849     printf(" or under the constraints k <= KMAX and h <= HMAX (i.e. in a rectangular\n");
1850     printf(" region of the integer lattice). This utility uses continued fraction\n");
1851     printf(" algorithms presented in the accompanying book \"A Practitioner's Guide\n");
1852     printf(" ...\", and this book (a work in progress) should be consulted both as a\n");
1853     printf(" reference to the algorithms and a reference for this utility. All\n");
1854     printf(" rational numbers calculated are in lowest terms. This utility will\n");
1855     printf(" operate on negative numbers, but all results are produced by symmetry\n");
1856     printf(" (the continued fraction representation of negative numbers is NOT\n");
1857     printf(" calculated). The default operation of this utility is to calculated the\n");
1858     printf(" closest rational number in the series of interest. If the rational\n");
1859     printf(" number supplied is equidistant between two formable rational numbers in\n");
1860     printf(" the series of interest, the neighbor smaller in magnitude is returned. If\n");
1861     printf(" the rational number supplied is already formable, it is returned in lowest\n");
1862     printf(" terms. If the rational number supplied does not have neighbors (i.e. it\n");
1863     printf(" is larger than HMAX/1), an error is generated.\n");
1864     printf("\n");
1865     printf("USAGE\n");
1866     printf(" cfbrapab srn urn_kmax [options]\n");
1867     printf(" cfbrapab srn urn_kmax urn_hmax [options]\n");
1868     printf(" cfbrapab -help\n");
1869     printf("\n");
1870     printf("OPTIONS\n");
1871     printf(" -neversmaller, -neverlarger\n");
1872     printf(" The -neversmaller option will prohibit this utility from choosing a\n");
1873     printf(" rational approximation which is smaller than the rational number\n");
1874     printf(" supplied. Thus, this option will force the utility to choose the right\n");
1875     printf(" neighbor rather than the left, regardless of relative distance. The\n");
1876     printf(" behavior if the rational number supplied is formable under the \n");
1877     printf(" constraints is unchanged. The -neverlarger option is analogous.\n");
1878     printf(" These options cannot be used with -n, -pred, or -succ.\n");
1879     printf(" -pred, -succ\n");
1880     printf(" Will cause the utility to find the predecessor or successor in the\n");
1881     printf(" series of interest to the rational number supplied (in the event the\n");
1882     printf(" number supplied is already formable under the constraints). For\n");
1883     printf(" numbers not already formable under the constraints, the left or right\n");
1884     printf(" formable neighbor will be returned. Supplying a rational number that\n");
1885     printf(" does not have a predecessor or successor (i.e. < 0/1 or > HMAX/1) will\n");
1886     printf(" generate an error. These options cannot be used with -neversmaller,\n");
1887     printf(" -neverlarger, or -n.\n");
1888     CU_MSGS_std_options(stdout, PNAME);
1889     FCMIOF_hline();
1890     CU_MSGS_toolset_info_msg(stdout, PNAME);
1891     FCMIOF_hline();
1892     }
1893     else if (argc < 3)
1894     {
1895     CU_MSGS_too_few_args_msg(stdout, PNAME);
1896     rv = 4;
1897     goto ret_pt;
1898     }
1899     else
1900     {
1901     //In this branch, we must have an invocation of the form
1902     // cfbrapab SRN KMAX <options>
1903     //or
1904     // cfbrapab SRN KMAX HMAX <options>
1905     //
1906     //Call the function to collect all the command-line parameters.
1907     //This function takes care of error processing, as well. If there
1908     //is an error of any kind, the function will simply abort and
1909     //supply the right return error code of 4.
1910     process_command_line_args(&parblock,
1911     argc,
1912     argv);
1913    
1914     //If the debug option was set, emit the debugging information.
1915     if (parblock.argblock.debug)
1916     {
1917     FCMIOF_hline();
1918     CU_MSGS_emit_vcinfo_from_ptr_table(stdout,C_MAIN_vcinfoptrs,PNAMEUC);
1919     }
1920    
1921     //Emit the opening horizontal line iff the -nf option isn't set.
1922     if (!(parblock.argblock.noformat))
1923     FCMIOF_hline();
1924    
1925     //Print out a major mode message to indicate what we are trying to do.
1926     if (!(parblock.argblock.noformat))
1927     {
1928     if (!parblock.neversmaller_specified && !parblock.neverlarger_specified && !parblock.pred_specified && !parblock.succ_specified)
1929     {
1930     printf("MAJOR MODE: Finding closest rational number(s) under the constraints.\n");
1931     }
1932     else if (parblock.neversmaller_specified)
1933     {
1934     printf("MAJOR MODE: Finding closest rational number with magnitude not smaller under\n the constraints.\n");
1935     }
1936     else if (parblock.neverlarger_specified)
1937     {
1938     printf("MAJOR MODE: Finding closest rational number with magnitude not larger under\n the constraints.\n");
1939     }
1940     else if (parblock.pred_specified)
1941     {
1942     printf("MAJOR MODE: Finding predecessor under the constraints.\n");
1943     }
1944     else if (parblock.succ_specified)
1945     {
1946     printf("MAJOR MODE: Finding successor under the constraints.\n");
1947     }
1948     else
1949     {
1950     assert(0);
1951     }
1952    
1953     FCMIOF_hline();
1954     }
1955    
1956     //Echo back the command-line parameters.
1957     if (!(parblock.argblock.noformat))
1958     {
1959     GMP_INTS_mpz_long_int_format_to_stream(stdout,
1960     &(parblock.rn.num),
1961     "RI_IN Numerator");
1962     FCMIOF_hline();
1963     GMP_INTS_mpz_long_int_format_to_stream(stdout,
1964     &(parblock.rn.den),
1965     "RI_IN Denominator");
1966     FCMIOF_hline();
1967    
1968     GMP_INTS_mpz_long_int_format_to_stream(stdout,
1969     &(parblock.kmax),
1970     "K_MAX");
1971     FCMIOF_hline();
1972    
1973     if (parblock.hmax_specified)
1974     {
1975     GMP_INTS_mpz_long_int_format_to_stream(stdout,
1976     &(parblock.hmax),
1977     "H_MAX");
1978     FCMIOF_hline();
1979     }
1980    
1981     if (parblock.n_specified)
1982     {
1983     GMP_INTS_mpz_struct temp24;
1984    
1985     GMP_INTS_mpz_init(&temp24);
1986    
1987     GMP_INTS_mpz_set_ui(&temp24, parblock.n);
1988    
1989     GMP_INTS_mpz_long_int_format_to_stream(stdout,
1990     &temp24,
1991     "Number Of Neighbors");
1992    
1993     FCMIOF_hline();
1994    
1995     GMP_INTS_mpz_clear(&temp24);
1996     }
1997     }
1998    
1999     //We need to split now into distinct cases
2000     //depending on the command-line parameters. We will
2001     //then hack out solutions for each case.
2002     if (!parblock.pred_specified && !parblock.succ_specified && !parblock.n_specified)
2003     {
2004     //Classic closest neighbor case.
2005     rv = CMAIN_classic_closest_neighbor(&parblock);
2006     }
2007     else if (parblock.n_specified)
2008     {
2009     //Classic multiple neighbor case.
2010     rv = CMAIN_multiple_neighbor(&parblock);
2011     }
2012     else if (parblock.pred_specified)
2013     {
2014     rv = CMAIN_predecessor(&parblock);
2015     }
2016     else if (parblock.succ_specified)
2017     {
2018     rv = CMAIN_successor(&parblock);
2019     }
2020     else
2021     {
2022     assert(0);
2023     }
2024    
2025     //Emit the closing horizontal line iff the -nf option isn't set.
2026     //if (!(parblock.argblock.noformat))
2027     // FCMIOF_hline();
2028    
2029     //Release all dynamic memory.
2030     release_command_line_args(&parblock);
2031     }
2032    
2033     ret_pt:
2034     return(rv);
2035     }
2036    
2037    
2038     //**************************************************************************
2039     // $Log: c_main.c,v $
2040     // Revision 1.6 2002/01/27 17:58:15 dtashley
2041     // CRC32, other programs modified to work under new directory structure.
2042     //
2043     // Revision 1.5 2001/08/16 19:49:36 dtashley
2044     // Beginning to prepare for v1.05 release.
2045     //
2046     // Revision 1.4 2001/08/15 06:55:59 dtashley
2047     // Substantial progress. Safety check-in.
2048     //
2049     // Revision 1.3 2001/08/12 10:20:58 dtashley
2050     // Safety check-in. Substantial progress.
2051     //
2052     // Revision 1.2 2001/07/26 03:53:17 dtashley
2053     // Utilities that are under constructions stubbed to announce this,
2054     // batch build file enhanced.
2055     //
2056     // Revision 1.1 2001/07/23 08:53:17 dtashley
2057     // Initial check-in.
2058     //
2059     //**************************************************************************
2060     // End of C_MAIN.C.

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25