1 /*==============================================================================
  2 | 
  3 |  File Name:     
  4 |
  5 |     ppIO.c
  6 |
  7 |  Description:   
  8 |
  9 |     Command line parsing and polynomial pretty printing.
 10 | 
 11 |  Functions:
 12 |
 13 |      parse_command_line
 14 |      write_poly
 15 |
 16 |  LEGAL
 17 |
 18 |     Primpoly Version 16.1 - A Program for Computing Primitive Polynomials.
 19 |     Copyright (C) 1999-2021 by Sean Erik O'Connor.  All Rights Reserved.
 20 |
 21 |     This program is free software: you can redistribute it and/or modify
 22 |     it under the terms of the GNU General Public License as published by
 23 |     the Free Software Foundation, either version 3 of the License, or
 24 |     (at your option) any later version.
 25 |
 26 |     This program is distributed in the hope that it will be useful,
 27 |     but WITHOUT ANY WARRANTY; without even the implied warranty of
 28 |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 29 |     GNU General Public License for more details.
 30 |
 31 |     You should have received a copy of the GNU General Public License
 32 |     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 33 |     
 34 |     The author's address is artificer!AT!seanerikoconnor!DOT!freeservers!DOT!com
 35 |     with !DOT! replaced by . and the !AT! replaced by @
 36 |
 37 ==============================================================================*/
 38 
 39 /*------------------------------------------------------------------------------
 40 |                                Include Files                                 |
 41 ------------------------------------------------------------------------------*/
 42 
 43 #include <stdio.h>  /* for printf()  */
 44 #include <stdlib.h> /* for _MAX_PATH */
 45 
 46 #include "Primpoly.h"
 47 
 48 
 49 /*==============================================================================
 50 |                               parse_command_line                             |
 51 ================================================================================
 52 
 53 DESCRIPTION
 54 
 55      Parse the command line.
 56 
 57 INPUT
 58                                                                      n
 59      a[]  (int *)  Coefficients of the nth degree polynomial a(x) = a x  + ...
 60                                                                      n
 61                    + a  x  +  a.    a  is stored at array location a[i], 
 62                       1        0     i
 63                    0 <= i < n .
 64 
 65      n    (int)    The polynomial's degree.
 66 
 67 OUTPUT
 68 
 69   testPolynomialForPrimitivity 
 70     
 71 
 72 EXAMPLE CALLING SEQUENCE
 73 
 74    pp -h                   Prints help.
 75    pp -s 2 4               Prints search statistics.
 76    pp -t 2 4 x^3+x^2+1     Checks a polynomial for primitivity.  No blanks, please!
 77    pp -a 2 4               Lists all primitive polynomials of degree 4 modulo 2.
 78    pp -c 2 4               Does a time-consuming double check on primitivity.
 79 
 80 METHOD
 81 
 82     
 83 
 84 BUGS
 85 
 86     None.
 87 
 88 
 89 --------------------------------------------------------------------------------
 90 |                                Function Call                                 |
 91 ------------------------------------------------------------------------------*/
 92 
 93 int parse_command_line( int    argc,
 94                         char * argv[],
 95                         int *  testPolynomialForPrimitivity,
 96                         int *  listAllPrimitivePolynomials,
 97                         int *  printStatistics,
 98                         int *  printHelp,
 99                         int *  selfCheck,
100                         int *  p,
101                         int *  n,
102                         int *  testPolynomial )
103 {
104 
105 int    input_arg_index ;
106 char * input_arg_string ;
107 char * option_ptr ;
108 
109 int    num_arg ;
110 char * arg_string[ _MAX_PATH ] ;
111 
112 /*  Initialize to defaults. */
113 *testPolynomialForPrimitivity = NO ;
114 *listAllPrimitivePolynomials  = NO ;
115 *printStatistics              = NO ;
116 *printHelp                    = NO ;
117 *selfCheck                    = NO ;
118 *p                            = 0 ;
119 *n                            = 0 ;
120 testPolynomial                = (int *) 0 ;
121 
122 
123 /*
124  *  Parse the command line to get the options and their inputs.
125  */
126 
127 for (input_arg_index = 0, num_arg = 0 ;  input_arg_index < argc ;
128      ++input_arg_index)
129 {
130     /*  Get next argument string. */
131     input_arg_string = argv[ input_arg_index ] ;
132 
133     /* We have an option:  a hyphen followed by a non-null string. */
134     if (input_arg_string[ 0 ] == '-' && input_arg_string[ 1 ] != '\0')
135     {
136         /* Scan all options. */
137         for (option_ptr = input_arg_string + 1 ;  *option_ptr != '\0' ;
138              ++option_ptr)
139         {
140             switch( *option_ptr )
141             {
142                 /* Test a given polynomial for primitivity. */
143                 case 't':
144                     *testPolynomialForPrimitivity = YES ;
145                 break ;
146 
147                 /* List all primitive polynomials.  */
148                 case 'a':
149                    *listAllPrimitivePolynomials = YES ;
150                 break ;
151 
152                 /* Print statistics on program operation. */
153                 case 's':
154                    *printStatistics = YES ;
155                 break ;
156 
157                 /* Print help. */
158                 case 'h':
159                 case 'H':
160                     *printHelp = YES ;
161                 break ;
162 
163                 /* Turn on all self-checking (slow!).  */
164                 case 'c':
165                     *selfCheck = YES ;
166                 break ;
167 
168                 default:
169                    printf( "Cannot recognize the option %c\n", *option_ptr ) ;
170                 break ;
171             }
172         }
173     }
174     else  /* Not an option, but an argument. */
175     {
176         arg_string[ num_arg++ ] = input_arg_string ;
177     }
178 }
179 
180 
181 /* Assume the next two arguments are p and n. */
182 if (num_arg == 3)
183 {
184     *p = atoi( arg_string[ 1 ] ) ;
185     *n = atoi( arg_string[ 2 ] ) ;
186 
187 }
188 else
189 {
190     printf( "ERROR:  Expecting two arguments, p and n.\n\n" ) ;
191     *printHelp = YES ;
192 }
193 
194 return 0 ;
195 
196 } /* ================ end of function parse_command_line ==================== */
197 
198 
199 /*==============================================================================
200 |                                    write_poly                                |
201 ================================================================================
202 
203 DESCRIPTION
204 
205      Print a polynomial in a nice format.  Omit terms with coefficients of zero.
206      Suppress coefficients of 1, but not the constant term.  Put every
207      NUMTERMSPERLINE terms in the polynomial on a new line.
208 
209 INPUT
210                                                                      n
211      a[]  (int *)  Coefficients of the nth degree polynomial a(x) = a x  + ...
212                                                                      n
213                    + a  x  +  a.    a  is stored at array location a[i], 
214                       1        0     i
215                    0 <= i < n .
216 
217      n    (int)    The polynomial's degree.
218 
219 OUTPUT
220 
221     Standard output    A pretty-printed polynomial.
222 
223 EXAMPLE CALLING SEQUENCE
224 
225     If array a[] contains 
226 
227     a[0] = 1
228     a[1] = 2
229     a[2] = 0
230     a[3] = 1
231 
232     and n = 3,
233 
234     write_poly( a, n ) prints
235 
236     x ^ 3  +  2 x  + 1
237 
238 METHOD
239 
240     Sheer hacking ingenuity (vulgarity?).
241 
242 BUGS
243 
244     None.
245 
246 --------------------------------------------------------------------------------
247 |                                Function Call                                 |
248 ------------------------------------------------------------------------------*/
249 
250 void write_poly( int * a, int n )
251 {
252 
253 /*------------------------------------------------------------------------------
254 |                               Local Variables                                |
255 ------------------------------------------------------------------------------*/
256 
257 int
258     k,                         /*  Loop conter. */
259     coeff,                     /*  Coefficient a sub k.  */
260     first_time_through = YES,  /* = NO after printing the first coefficient. */
261     num_terms = 0 ;            /*  Number of terms printed so far.  */
262 
263 /*------------------------------------------------------------------------------
264 |                                Function Body                                 |
265 ------------------------------------------------------------------------------*/
266 
267 for (k = n ;  k >= 0 ;  --k)
268 {
269 
270     /*                    
271                       k 
272     Print the term a x  if a  is nonzero.
273                     k       k
274     */
275 
276     if ( (coeff = a[ k ]) != 0)
277     {
278 
279        /* After the first time thorough, print leading plus signs "+" to 
280           separate the terms of the polynomial. */
281 
282         if (!first_time_through)
283 
284             printf( " + " ) ;
285 
286         first_time_through = NO ;
287 
288         /* Always print the constant term a  but print terms of higher degree
289                                            0 
290            only if a  is not 1.
291                     k             */
292 
293         if ( (coeff != 1) || (k == 0) )
294 
295             printf( "%d", coeff ) ;
296 
297 
298         /*                  k                             1      0
299             Print the term x.  Exceptions:  print x, not x, omit x  */
300 
301         if (k > 1)
302 
303             printf( " x ^ %d", k ) ;
304 
305         else if (k == 1)
306 
307             printf( " x" ) ;
308 
309         /*  Start a new line. */
310 
311         if (++num_terms % NUMTERMSPERLINE == 0)
312 
313             printf( "\n" ) ;
314 
315     } /* end if coeff > 0 */
316 
317 } /* end for */
318 
319 printf( "\n" ) ;
320 
321 return ;
322 
323 } /* ======================= end of function write_poly ===================== */