ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/xyz2pov/src/xyz2pov.c
Revision: 2750
Committed: Fri May 12 19:24:30 2006 UTC (18 years, 11 months ago) by tim
Content type: text/plain
File size: 36276 byte(s)
Log Message:
adding support for Gay-Berne atom

File Contents

# User Rev Content
1 mmeineke 1095 #define _FILE_OFFSET_BITS 64
2    
3 mmeineke 60 #include <stdio.h>
4     #include <stdlib.h>
5     #include <string.h>
6     #include <math.h>
7     #include <unistd.h>
8     #include <sys/types.h>
9     #include <sys/stat.h>
10    
11     #include "frameCount.h"
12     #include "atom_parser.h"
13     #include "pov_writer.h"
14    
15    
16     #define POV_DIR "./pov"
17    
18 mmeineke 508
19 mmeineke 60 struct linked_xyz{
20     struct coords *r;
21 gezelter 625 double Hmat[3][3];
22 mmeineke 60 struct linked_xyz *next;
23     };
24    
25     char *program_name; /*the name of the program */
26     int draw_bonds = 0; /* boolean to draw bonds or not */
27     int draw_hydrogens = 0; /*boolean to draw hydrogens */
28     int draw_atoms = 0; /*boolean to draw atoms */
29 gezelter 864 int draw_vectors = 0; /*boolean to draw vectors */
30 mmeineke 515 int draw_box = 0; // boolean to draw the periodic Box
31 mmeineke 508 int regenerateBonds = 0; // boolean to regenearate bonds each frame
32 mmeineke 60
33     void usage(void);
34 gezelter 864 int count_tokens(char *line, char *delimiters);
35 mmeineke 60
36     int main(argc, argv)
37     int argc;
38     char *argv[];
39     {
40    
41    
42     struct coords *out_coords;
43    
44 gezelter 625 int i,j,k; /* loop counters */
45 mmeineke 60 mode_t dir_mode = S_IRWXU;
46    
47     int generate_header = 0; /* boolean for generating the pov ray header */
48     double big_x = 0;
49     double big_y = 0; /* lets me know the biggest x y and z */
50     double big_z = 0;
51     double small_x = 0;
52     double small_y = 0; /* lets me know the smallest x, y, z */
53     double small_z = 0;
54 gezelter 864 int extremaSet = 0;
55 mmeineke 60 double rsqr; /* the square of the diagonal */
56     double diagonal; /* the diagonal length of the sim box */
57    
58     unsigned int n_atoms; /*the number of atoms in each time step */
59 mmeineke 649 char read_buffer[2000]; /*the line buffer for reading */
60 mmeineke 60 char *eof_test; /*ptr to see when we reach the end of the file */
61     char *foo; /*the pointer to the current string token */
62     FILE *in_file; /* the input file */
63     FILE *out_file; /*the output file */
64     char *out_prefix = NULL; /*the prefix of the output file */
65     int have_prefix = 0;
66     char out_name[500]; /*the output name */
67     char out_format[1000];
68     char *in_name = NULL; /*the name of the input file */
69     unsigned int n_out = 0; /*keeps track of which output file is being written*/
70     int done;
71     char current_flag;
72     int nFrames;
73     int nZeroes;
74 gezelter 864 int nTokens;
75 mmeineke 60 double count;
76    
77 mmeineke 515 int startFrame = 1;
78     int endFrame;
79     int span = 0;
80     int currentCount = 0;
81     int haveEnd = 0;
82    
83 mmeineke 60 struct linked_xyz *current_frame;
84     struct linked_xyz *temp_frame;
85    
86     unsigned int n_interpolate = 0; /* number of frames to interpolate */
87     double dx, dy, dz; /* temp variables for interpolating distances */
88 gezelter 625 double dm[3][3];
89 mmeineke 515
90 mmeineke 60
91     char pov_dir[500]; /* the pov_dir */
92    
93     program_name = argv[0]; /*save the program name in case we need it*/
94    
95 mmeineke 508
96 mmeineke 60 for( i = 1; i < argc; i++){
97    
98     if(argv[i][0] =='-'){
99    
100     // parse the option
101    
102     if(argv[i][1] == '-' ){
103    
104     // parse long word options
105    
106     fprintf( stderr,
107     "Invalid option \"%s\"\n", argv[i] );
108     usage();
109    
110     }
111    
112     else{
113    
114     // parse single character options
115    
116     done = 0;
117     j = 1;
118     current_flag = argv[i][j];
119     while( (current_flag != '\0') && (!done) ){
120    
121     switch(current_flag){
122    
123     case 'o':
124     // -o <prefix> => the output prefix.
125    
126     i++;
127     out_prefix = argv[i];
128     have_prefix = 1;
129     done = 1;
130     break;
131    
132     case 'i':
133     // -i <#> => the number to interpolate
134    
135     i++;
136     n_interpolate = atoi( argv[i] );
137     done = 1;
138     break;
139    
140 mmeineke 515 case 'f':
141     // -f <#> => frame to render
142    
143     i++;
144     startFrame = atoi( argv[i] );
145     endFrame = startFrame;
146     haveEnd = 1;
147     done = 1;
148     break;
149    
150     case 's':
151     // -s <#> => frame to start
152    
153     i++;
154     startFrame = atoi( argv[i] );
155     done = 1;
156     break;
157    
158     case 'e':
159     // -e <#> => frame to end
160    
161     i++;
162     endFrame = atoi( argv[i] );
163     haveEnd = 1;
164     done = 1;
165     break;
166    
167 mmeineke 60 case 'H':
168     // -h => generate a pov-ray Header
169    
170     generate_header = 1;
171     break;
172    
173     case 'h':
174     // -h => draw Hydrogens
175    
176     draw_hydrogens = 1;
177     break;
178    
179     case 'b':
180     // -b => draw bonds
181    
182     draw_bonds = 1;
183     break;
184    
185     case 'a':
186     // -a => draw the atoms
187    
188     draw_atoms = 1;
189     break;
190    
191 gezelter 864 case 'v':
192     // -v => draw the vectors
193    
194     draw_vectors = 1;
195     break;
196    
197 mmeineke 508 case 'r':
198     // -r => regenerate bonds
199    
200     regenerateBonds = 1;
201     break;
202    
203 mmeineke 515 case 'p':
204     // -r => draw periodic box
205    
206     draw_box = 1;
207     break;
208    
209 mmeineke 60 default:
210    
211     (void)fprintf(stderr, "Bad option \"-%c\"\n", current_flag);
212     usage();
213     }
214     j++;
215     current_flag = argv[i][j];
216     }
217     }
218     }
219    
220     else{
221    
222     if( in_name != NULL ){
223     fprintf( stderr,
224     "Error at \"%s\", program does not currently support\n"
225     "more than one input file.\n"
226     "\n",
227     argv[i]);
228     usage();
229     }
230    
231     in_name = argv[i];
232     }
233     }
234    
235     if(in_name == NULL){
236     usage();
237     }
238    
239    
240    
241     in_file = fopen(in_name, "r");
242     if(in_file == NULL){
243     printf("Cannot open file: %s\n", in_name);
244     exit(8);
245     }
246    
247    
248    
249     if(access(POV_DIR, F_OK)){
250     /*create the pov directory*/
251     mkdir(POV_DIR, dir_mode);
252     }
253     strcpy(pov_dir, POV_DIR); strcat(pov_dir, "/");
254    
255    
256     // initialize atom type parser
257    
258     initializeParser();
259 mmeineke 508 initBondList();
260 mmeineke 60
261     // count the number of frames
262    
263     printf( "Counting the number of frames..." );
264     fflush(stdout);
265    
266     nFrames = frameCount( in_name );
267    
268     printf( "done.\n"
269     "%d frames found\n",
270     nFrames);
271     fflush(stdout);
272    
273     // create the output string
274    
275     nZeroes = 1;
276     count = (double)( nFrames * (n_interpolate+1) );
277     while( count >= 10.0 ){
278     count /= 10.0;
279     nZeroes++;
280     }
281    
282     if(!have_prefix){
283     out_prefix = strtok(in_name, ".");
284     }
285    
286 mmeineke 649 sprintf( out_format, "%s%s-%%0%dd.pov", pov_dir, out_prefix, nZeroes );
287 mmeineke 60
288     // start reading the first frame
289    
290     eof_test = fgets(read_buffer, sizeof(read_buffer), in_file);
291    
292     current_frame = (struct linked_xyz *)malloc(sizeof(struct linked_xyz));
293     current_frame->next = NULL;
294    
295    
296 mmeineke 515 if( haveEnd ) span = endFrame - startFrame;
297     done = 0;
298     if( span < 0 ) done = 1;
299     while( (eof_test != NULL) && !done ){
300 mmeineke 60
301     (void)sscanf(read_buffer, "%d", &n_atoms);
302     current_frame->r =
303     (struct coords *)calloc(n_atoms, sizeof(struct coords));
304    
305     /*read and toss the comment line */
306    
307     eof_test = fgets(read_buffer, sizeof(read_buffer), in_file);
308     if(eof_test == NULL){
309     printf("error in reading file\n");
310     exit(8);
311     }
312 mmeineke 515
313     // unless we need to get the box size
314    
315     if( draw_box ){
316     foo = strtok(read_buffer, " ,;\t");
317     if(foo == NULL){
318 mmeineke 649 printf("error in reading file time\n");
319 mmeineke 515 exit(8);
320     }
321    
322     foo = strtok(NULL, " ,;\t");
323     if(foo == NULL){
324 mmeineke 649 printf("error in reading file h00\n");
325 mmeineke 515 exit(8);
326     }
327 gezelter 625 current_frame->Hmat[0][0] = atof( foo );
328 mmeineke 60
329 mmeineke 515 foo = strtok(NULL, " ,;\t");
330     if(foo == NULL){
331 mmeineke 649 printf("error in reading file h10\n");
332 mmeineke 515 exit(8);
333     }
334 gezelter 625 current_frame->Hmat[1][0] = atof( foo );
335 mmeineke 515
336     foo = strtok(NULL, " ,;\t");
337     if(foo == NULL){
338 mmeineke 649 printf("error in reading file h20\n");
339 mmeineke 515 exit(8);
340     }
341 gezelter 625 current_frame->Hmat[2][0] = atof( foo );
342    
343     foo = strtok(NULL, " ,;\t");
344     if(foo == NULL){
345 mmeineke 649 printf("error in reading file h01\n");
346 gezelter 625 exit(8);
347     }
348     current_frame->Hmat[0][1] = atof( foo );
349    
350     foo = strtok(NULL, " ,;\t");
351     if(foo == NULL){
352 mmeineke 649 printf("error in reading file h11\n");
353 gezelter 625 exit(8);
354     }
355     current_frame->Hmat[1][1] = atof( foo );
356    
357     foo = strtok(NULL, " ,;\t");
358     if(foo == NULL){
359 mmeineke 649 printf("error in reading file h21\n");
360 gezelter 625 exit(8);
361     }
362     current_frame->Hmat[2][1] = atof( foo );
363    
364     foo = strtok(NULL, " ,;\t");
365     if(foo == NULL){
366 mmeineke 649 printf("error in reading file h02\n");
367 gezelter 625 exit(8);
368     }
369     current_frame->Hmat[0][2] = atof( foo );
370    
371     foo = strtok(NULL, " ,;\t");
372     if(foo == NULL){
373 mmeineke 649 printf("error in reading file h12\n");
374 gezelter 625 exit(8);
375     }
376     current_frame->Hmat[1][2] = atof( foo );
377    
378     foo = strtok(NULL, " ,;\t");
379     if(foo == NULL){
380 mmeineke 649 printf("error in reading file h22\n");
381 gezelter 625 exit(8);
382     }
383     current_frame->Hmat[2][2] = atof( foo );
384    
385 mmeineke 515 }
386    
387 mmeineke 60 for( i=0; i < n_atoms; i++){
388    
389     eof_test = fgets(read_buffer, sizeof(read_buffer), in_file);
390     if(eof_test == NULL){
391 mmeineke 649 printf("error in reading file line at atom %d\n", i);
392 mmeineke 60 exit(8);
393     }
394    
395 gezelter 864 nTokens = count_tokens(read_buffer, " ,;\t");
396    
397     if (nTokens < 4) {
398     printf("Not enough tokens while parsing file at atom %d\n", i);
399     exit(8);
400     }
401    
402 mmeineke 60 foo = strtok(read_buffer, " ,;\t");
403     (void)strcpy(current_frame->r[i].name, foo); /*copy the atom name */
404    
405     foo = strtok(NULL, " ,;\t");
406     (void)sscanf(foo, "%lf",&current_frame->r[i].x);
407     foo = strtok(NULL, " ,;\t");
408     (void)sscanf(foo, "%lf", &current_frame->r[i].y);
409 gezelter 864 foo = strtok(NULL, " ,;\t");
410     (void)sscanf(foo, "%lf", &current_frame->r[i].z);
411 mmeineke 60
412 gezelter 864 if (extremaSet) {
413     if(current_frame->r[i].x > big_x) big_x = current_frame->r[i].x;
414     if(current_frame->r[i].x < small_x) small_x = current_frame->r[i].x;
415    
416     if(current_frame->r[i].y > big_y) big_y = current_frame->r[i].y;
417     if(current_frame->r[i].y < small_y) small_y = current_frame->r[i].y;
418    
419     if(current_frame->r[i].z > big_z) big_z = current_frame->r[i].z;
420     if(current_frame->r[i].z < small_z) small_z = current_frame->r[i].z;
421     } else {
422     big_x = current_frame->r[i].x;
423     small_x = current_frame->r[i].x;
424    
425     big_y = current_frame->r[i].y;
426     small_y = current_frame->r[i].y;
427    
428     big_z = current_frame->r[i].z;
429     small_z = current_frame->r[i].z;
430 mmeineke 60
431 gezelter 864 extremaSet = 1;
432    
433 mmeineke 60 }
434    
435 gezelter 864 if (nTokens == 5 || nTokens > 7) {
436     foo = strtok(NULL, " ,;\t");
437     (void)sscanf(foo, "%lf", &current_frame->r[i].charge);
438     current_frame->r[i].hasCharge = 1;
439     } else {
440     current_frame->r[i].hasCharge = 0;
441     }
442    
443    
444     if (nTokens >= 7) {
445     foo = strtok(NULL, " ,;\t");
446     (void)sscanf(foo, "%lf", &current_frame->r[i].ux);
447     foo = strtok(NULL, " ,;\t");
448     (void)sscanf(foo, "%lf", &current_frame->r[i].uy);
449     foo = strtok(NULL, " ,;\t");
450     (void)sscanf(foo, "%lf", &current_frame->r[i].uz);
451     current_frame->r[i].hasVector = 1;
452     } else {
453     current_frame->r[i].hasVector = 0;
454     }
455 tim 2750
456     if (nTokens >= 10) {
457     foo = strtok(NULL, " ,;\t");
458     (void)sscanf(foo, "%lf", &current_frame->r[i].vx);
459     foo = strtok(NULL, " ,;\t");
460     (void)sscanf(foo, "%lf", &current_frame->r[i].vy);
461     foo = strtok(NULL, " ,;\t");
462     (void)sscanf(foo, "%lf", &current_frame->r[i].vz);
463     current_frame->r[i].hasSecondVector = 1;
464     } else {
465     current_frame->r[i].hasSecondVector = 0;
466     }
467    
468    
469    
470 mmeineke 60 }
471 mmeineke 515 currentCount++;
472 mmeineke 60
473 mmeineke 515
474     if( currentCount >= startFrame ){
475     if(n_interpolate && current_frame->next != NULL){
476 mmeineke 60
477 mmeineke 515 temp_frame = current_frame->next;
478 mmeineke 60
479 mmeineke 515 for(i = 0; i < n_interpolate; i++){
480    
481     /* open the new output file */
482    
483     sprintf(out_name, out_format, currentCount );
484     out_file = fopen(out_name, "w");
485     currentCount++;
486     if(out_file == NULL){
487     printf("error opening output file: %s\n", out_name);
488     exit(8);
489     }
490     (void)fprintf(out_file,
491     "// The following script was automatically generated by:\n"
492     "// xyz2pov Copyright 2001 by MATTHEW A. MEINEKE\n"
493     "\n"
494     "#include \"pov_header.pov\"\n"
495     "\n");
496     if( draw_box ){
497 gezelter 625
498     for (j = 0; j < 3; j++) {
499     for (k = 0; k < 3; k++) {
500     dm[j][k] = current_frame->Hmat[j][k] - temp_frame->Hmat[j][k];
501     dm[j][k] /= (double)(n_interpolate + 1);
502     }
503     }
504    
505 mmeineke 515 fprintf( out_file,
506 gezelter 625 "makePeriodicBox( %lf, %lf, %lf, %lf, %lf, %lf, %lf, %lf, %lf)\n"
507 mmeineke 515 "\n",
508 gezelter 625 temp_frame->Hmat[0][0] + dm[0][0] * (i+1),
509 mmeineke 629 temp_frame->Hmat[2][0] + dm[2][0] * (i+1),
510 gezelter 625 temp_frame->Hmat[1][0] + dm[1][0] * (i+1),
511     temp_frame->Hmat[0][1] + dm[0][1] * (i+1),
512 mmeineke 629 temp_frame->Hmat[2][1] + dm[2][1] * (i+1),
513 gezelter 625 temp_frame->Hmat[1][1] + dm[1][1] * (i+1),
514     temp_frame->Hmat[0][2] + dm[0][2] * (i+1),
515 mmeineke 629 temp_frame->Hmat[2][2] + dm[2][2] * (i+1),
516     temp_frame->Hmat[1][2] + dm[1][2] * (i+1) );
517 mmeineke 515 }
518    
519    
520     out_coords =
521     (struct coords *)calloc(n_atoms, sizeof(struct coords));
522    
523     for(j=0; j < n_atoms; j++){
524     dx = current_frame->r[j].x - temp_frame->r[j].x;
525     dy = current_frame->r[j].y - temp_frame->r[j].y;
526     dz = current_frame->r[j].z - temp_frame->r[j].z;
527    
528     dx /= (double)(n_interpolate + 1);
529     dy /= (double)(n_interpolate + 1);
530     dz /= (double)(n_interpolate + 1);
531    
532     strcpy(out_coords[j].name, temp_frame->r[j].name);
533     out_coords[j].x = temp_frame->r[j].x + dx * (i+1);
534     out_coords[j].y = temp_frame->r[j].y + dy * (i+1);
535     out_coords[j].z = temp_frame->r[j].z + dz * (i+1);
536 gezelter 864
537     if (current_frame->r[j].hasVector) {
538     dx = current_frame->r[j].ux - temp_frame->r[j].ux;
539     dy = current_frame->r[j].uy - temp_frame->r[j].uy;
540     dz = current_frame->r[j].uz - temp_frame->r[j].uz;
541    
542     dx /= (double)(n_interpolate + 1);
543     dy /= (double)(n_interpolate + 1);
544     dz /= (double)(n_interpolate + 1);
545    
546     out_coords[j].hasVector = current_frame->r[j].hasVector;
547     out_coords[j].ux = temp_frame->r[j].ux + dx * (i+1);
548     out_coords[j].uy = temp_frame->r[j].uy + dy * (i+1);
549     out_coords[j].uz = temp_frame->r[j].uz + dz * (i+1);
550     }
551    
552 tim 2750 if (current_frame->r[j].hasSecondVector) {
553     dx = current_frame->r[j].vx - temp_frame->r[j].vx;
554     dy = current_frame->r[j].vy - temp_frame->r[j].vy;
555     dz = current_frame->r[j].vz - temp_frame->r[j].vz;
556    
557     dx /= (double)(n_interpolate + 1);
558     dy /= (double)(n_interpolate + 1);
559     dz /= (double)(n_interpolate + 1);
560    
561     out_coords[j].hasVector = current_frame->r[j].hasSecondVector;
562     out_coords[j].vx = temp_frame->r[j].vx + dx * (i+1);
563     out_coords[j].vy = temp_frame->r[j].vy + dy * (i+1);
564     out_coords[j].vz = temp_frame->r[j].vz + dz * (i+1);
565     }
566    
567 gezelter 864 if (current_frame->r[j].hasCharge) {
568     dx = current_frame->r[j].charge - temp_frame->r[j].charge;
569    
570     dx /= (double)(n_interpolate + 1);
571    
572     out_coords[j].hasCharge = current_frame->r[j].hasCharge;
573     out_coords[j].charge = temp_frame->r[j].charge + dx * (i+1);
574     }
575    
576 mmeineke 515 }
577    
578     pov_write(out_file, out_coords, n_atoms, draw_hydrogens, draw_bonds,
579 gezelter 864 draw_atoms, draw_vectors);
580 mmeineke 515 free(out_coords);
581     (void)fclose(out_file);
582 mmeineke 60 }
583 mmeineke 515 }
584    
585     /* open the new output file */
586    
587     sprintf(out_name, out_format, currentCount );
588     out_file = fopen(out_name, "w");
589     if(out_file == NULL){
590     printf("error opening output file: %s\n", out_name);
591     exit(8);
592     }
593     (void)fprintf(out_file,
594     "// The following script was automatically generated by:\n"
595     "// xyz2pov Copyright 2001 by MATTHEW A. MEINEKE\n"
596     "\n"
597     "#include \"pov_header.pov\"\n"
598     "\n");
599    
600     if( draw_box ){
601 mmeineke 60
602 mmeineke 515 fprintf( out_file,
603 gezelter 630 "makePeriodicBox( %lf, %lf, %lf, %lf, %lf, %lf, %lf, %lf, %lf )\n"
604 mmeineke 515 "\n",
605 gezelter 625 current_frame->Hmat[0][0],
606 mmeineke 629 current_frame->Hmat[2][0],
607 gezelter 625 current_frame->Hmat[1][0],
608     current_frame->Hmat[0][1],
609 mmeineke 629 current_frame->Hmat[2][1],
610 gezelter 625 current_frame->Hmat[1][1],
611     current_frame->Hmat[0][2],
612 mmeineke 629 current_frame->Hmat[2][2],
613     current_frame->Hmat[1][2] );
614 mmeineke 60 }
615 mmeineke 515
616    
617    
618     out_coords =
619     (struct coords *)calloc(n_atoms, sizeof(struct coords));
620    
621     for(i = 0; i < n_atoms; i++){
622     strcpy(out_coords[i].name, current_frame->r[i].name);
623     out_coords[i].x = current_frame->r[i].x;
624     out_coords[i].y = current_frame->r[i].y;
625     out_coords[i].z = current_frame->r[i].z;
626 gezelter 864
627     if (current_frame->r[i].hasVector) {
628     out_coords[i].hasVector = current_frame->r[i].hasVector;
629     out_coords[i].ux = current_frame->r[i].ux;
630     out_coords[i].uy = current_frame->r[i].uy;
631     out_coords[i].uz = current_frame->r[i].uz;
632     }
633    
634 tim 2750 if (current_frame->r[i].hasSecondVector) {
635     out_coords[i].hasSecondVector = current_frame->r[i].hasSecondVector;
636     out_coords[i].vx = current_frame->r[i].vx;
637     out_coords[i].vy = current_frame->r[i].vy;
638     out_coords[i].vz = current_frame->r[i].vz;
639     }
640    
641 gezelter 864 if (current_frame->r[i].hasCharge) {
642     out_coords[i].hasCharge = current_frame->r[i].hasCharge;
643     out_coords[i].charge = current_frame->r[i].charge;
644     }
645 mmeineke 515 }
646     pov_write(out_file, out_coords, n_atoms, draw_hydrogens, draw_bonds,
647 gezelter 864 draw_atoms, draw_vectors);
648 mmeineke 515 free(out_coords);
649    
650     (void)fclose(out_file);
651 mmeineke 60 }
652    
653     /*free up memory */
654    
655     temp_frame = current_frame->next;
656     current_frame->next = NULL;
657    
658     if(temp_frame != NULL){
659    
660     free(temp_frame->r);
661     free(temp_frame);
662     }
663    
664     /* make a new frame */
665    
666     temp_frame = (struct linked_xyz *)malloc(sizeof(struct linked_xyz));
667     temp_frame->next = current_frame;
668     current_frame = temp_frame;
669    
670     eof_test = fgets(read_buffer, sizeof(read_buffer), in_file);
671    
672 mmeineke 515 if( haveEnd ){
673     if( currentCount >= (endFrame + n_interpolate * span) ) done = 1;
674     }
675 mmeineke 60 }
676    
677     (void)fclose(in_file);
678    
679    
680     if(generate_header){
681    
682     dx = big_x - small_x;
683     dy = big_y - small_y;
684     dz = big_z - small_z;
685    
686     rsqr = dx * dx + dy * dy + dz * dz;
687     diagonal = sqrt(rsqr);
688     diagonal *= 0.5;
689    
690 mmeineke 515 // calculate the center
691    
692     dx = big_x + small_x;
693     dy = big_y + small_y;
694     dz = big_z + small_z;
695    
696 mmeineke 60 dx /= 2.0;
697     dy /= 2.0;
698     dz /= 2.0;
699 mmeineke 515
700 mmeineke 60
701     /*note the y and z axis is exchanged for the different coordinate
702     system in pov-ray*/
703    
704    
705     out_file = fopen("pov_header.pov", "w");
706    
707     fprintf(out_file,
708     "// The following script was automatically generated by:\n"
709     "// xyz2pov Copyright 2001 by MATTHEW A. MEINEKE\n"
710 tim 2750 "#include \"colors.inc\"\n"
711     "#include \"math.inc\"\n"
712 mmeineke 60 "\n"
713     "\n"
714     "background { rgb <1.0, 1.0, 1.0> }\n"
715     "\n"
716     "\n"
717     );
718    
719     fprintf(out_file,
720     "//******************************************************\n"
721     "// Declare the resolution, camera, and light sources.\n"
722     "//******************************************************\n"
723     "\n"
724     "// NOTE: if you plan to render at a different resoltion,\n"
725     "// be sure to update the following two lines to maintain\n"
726     "// the correct aspect ratio.\n"
727     "\n"
728     "#declare Width = 640.0;\n"
729     "#declare Height = 480.0;\n"
730     "#declare Ratio = Width / Height;\n"
731     "\n"
732     "#declare ATOM_SPHERE_FACTOR = 0.2;\n"
733     "#declare BOND_RADIUS = 0.1;\n"
734 gezelter 864 "#declare VECTOR_SCALE = 1.0;\n"
735     "#declare STICK_RADIUS = 0.5 * BOND_RADIUS;\n"
736     "#declare CONE_RADIUS = 2.0 * STICK_RADIUS;\n"
737     "#declare CONE_FRACTION = 0.15;\n"
738 mmeineke 60 "\n"
739 mmeineke 515 "// declare camera, light, and system variables\n"
740     "\n"
741     "#declare sysCenterX = %lf;\n"
742     "#declare sysCenterY = %lf;\n"
743     "#declare sysCenterZ = %lf;\n"
744     "\n"
745     "#declare zoom = %lf;\n"
746     "\n",
747     dx, dz, dy,
748     diagonal );
749    
750     fprintf(out_file,
751     "#declare cameraLookX = sysCenterX;\n"
752     "#declare cameraLookY = sysCenterY;\n"
753     "#declare cameraLookZ = sysCenterZ;\n"
754     "\n"
755 gezelter 868 "#declare rotatePointX = cameraLookX;\n"
756     "#declare rotatePointY = cameraLookY;\n"
757     "#declare rotatePointZ = cameraLookZ;\n"
758     "\n"
759 mmeineke 515 "#declare cameraX = cameraLookX;\n"
760     "#declare cameraY = cameraLookY;\n"
761     "#declare cameraZ = cameraLookZ - zoom;\n"
762     "\n"
763     "#declare lightAx = cameraX;\n"
764     "#declare lightAy = cameraY;\n"
765     "#declare lightAz = cameraZ;\n"
766     "\n"
767     "#declare lightBx = cameraX - zoom;\n"
768     "#declare lightBy = cameraY + zoom;\n"
769     "#declare lightBz = cameraZ;\n"
770     "\n"
771     "#declare boxCenterX = cameraLookX;\n"
772     "#declare boxCenterY = cameraLookY;\n"
773     "#declare boxCenterZ = cameraLookZ;\n"
774 tim 2750 "#declare fn = function(x,y,z) {(y+1)/2}\n"
775     "#declare grad1 = pigment { function { fn(x, y, z) } color_map {[0.0 rgb <0,0,0>] [1.0 rgb <3,0,0>]} };\n"
776     "#declare grad2 = pigment { function { fn(x, y, z) } rotate 120*z color_map {[0.0 rgb <0,0,0>] [1.0 rgb <0,3,0>]} };\n"
777     "#declare grad3 = pigment { function { fn(x, y, z) } rotate 240*z color_map {[0.0 rgb <0,0,0>] [1.0 rgb <0,0,3>]} };\n"
778     "#declare fnz = function(x,y,z) {(z+1)/2}\n"
779     "#declare gradz = pigment { function { fnz(x, y, z) } color_map {[0.0 rgb <0,0,0>] [1.0 rgb <1,1,1>]} };\n"
780 mmeineke 515 "\n"
781     "// declare the cameras and the light sources\n"
782     "\n"
783 mmeineke 60 "camera{\n"
784 mmeineke 515 " location < cameraX, cameraY, cameraZ>\n"
785 mmeineke 60 " right < Ratio , 0, 0>\n"
786 mmeineke 515 " look_at < cameraLookX, cameraLookY, cameraLookZ >\n"
787 mmeineke 60 "}\n"
788 mmeineke 515 "\n"
789 mmeineke 60 "light_source{\n"
790 mmeineke 515 " < lightAx, lightAy, lightAz >\n"
791     " rgb < 1.0, 1.0, 1.0 > }\n"
792     "\n"
793 mmeineke 60 "light_source{\n"
794 mmeineke 515 " < lightBx, lightBy, lightBz >\n"
795 mmeineke 60 " rgb < 1.0, 1.0, 1.0 > }\n"
796     "\n"
797 mmeineke 515 "\n"
798 mmeineke 60 "//************************************************************\n"
799     "// Set whether or not to rotate the system.\n"
800     "//\n"
801     "// To Rotate, set ROTATE to 1.0 (true),\n"
802     "// Then set the Euler Angles PHI, THETA, and PSI in degrees.\n"
803     "//************************************************************\n"
804     "\n"
805     "#declare ROTATE = 0.0;\n"
806     "#declare PHI = 0.0;\n"
807     "#declare THETA = 0.0;\n"
808     "#declare PSI = 0.0;\n"
809     "\n"
810     "#if(ROTATE)\n"
811     " #declare phi_r = radians(PHI);\n"
812     " #declare theta_r = radians(THETA);\n"
813     " #declare psi_r = radians(PSI);\n"
814     "\n"
815     " #declare A11 = cos(phi_r) * cos(psi_r) - sin(phi_r) * cos(theta_r) * sin(psi_r);\n"
816     " #declare A12 = sin(phi_r) * cos(psi_r) + cos(phi_r) * cos(theta_r) * sin(psi_r);\n"
817     " #declare A13 = sin(theta_r) * sin(psi_r);\n"
818     "\n"
819     " #declare A21 = -cos(phi_r) * sin(psi_r) - sin(phi_r) * cos(theta_r) * cos(psi_r);\n"
820     " #declare A22 = -sin(phi_r) * sin(psi_r) + cos(phi_r) * cos(theta_r) * cos(psi_r);\n"
821     " #declare A23 = sin(theta_r) * cos(psi_r);\n"
822     "\n"
823     " #declare A31 = sin(phi_r) * sin(theta_r);\n"
824     " #declare A32 = -cos(phi_r) * sin(theta_r);\n"
825     " #declare A33 = cos(theta_r);\n"
826     "\n"
827     "#end\n"
828 mmeineke 515 "\n"
829     "\n"
830     "//************************************************************\n"
831     "// declare the periodic box macro\n"
832     "//************************************************************\n"
833     "\n"
834 gezelter 625 "#macro makePeriodicBox( bx1, by1, bz1, bx2, by2, bz2, bx3, by3, bz3 )\n"
835 mmeineke 515 "\n"
836 mmeineke 629 " #local bcx = (bx1 + bx2 + bx3) / 2.0;\n"
837     " #local bcy = (by1 + by2 + by3) / 2.0;\n"
838     " #local bcz = (bz1 + bz2 + bz3) / 2.0;\n"
839 mmeineke 515 "\n"
840 mmeineke 629 " #local pAx = boxCenterX - bcx;\n"
841     " #local pAy = boxCenterY - bcy;\n"
842     " #local pAz = boxCenterZ - bcz;\n"
843     " #local pBx = boxCenterX + bx1 - bcx;\n"
844     " #local pBy = boxCenterY + by1 - bcy;\n"
845     " #local pBz = boxCenterZ + bz1 - bcz;\n"
846     " #local pCx = boxCenterX + bx2 - bcx;\n"
847     " #local pCy = boxCenterY + by2 - bcy;\n"
848     " #local pCz = boxCenterZ + bz2 - bcz;\n"
849     " #local pDx = boxCenterX + bx3 - bcx;\n"
850     " #local pDy = boxCenterY + by3 - bcy;\n"
851     " #local pDz = boxCenterZ + bz3 - bcz;\n"
852     " #local pEx = boxCenterX + bx1 + bx2 - bcx;\n"
853     " #local pEy = boxCenterY + by1 + by2 - bcy;\n"
854     " #local pEz = boxCenterZ + bz1 + bz2 - bcz;\n"
855     " #local pFx = boxCenterX + bx1 + bx3 - bcx;\n"
856     " #local pFy = boxCenterY + by1 + by3 - bcy;\n"
857     " #local pFz = boxCenterZ + bz1 + bz3 - bcz;\n"
858     " #local pGx = boxCenterX + bx2 + bx3 - bcx;\n"
859     " #local pGy = boxCenterY + by2 + by3 - bcy;\n"
860     " #local pGz = boxCenterZ + bz2 + bz3 - bcz;\n"
861     " #local pHx = boxCenterX + bx1 + bx2 + bx3 - bcx;\n"
862     " #local pHy = boxCenterY + by1 + by2 + by3 - bcy;\n"
863     " #local pHz = boxCenterZ + bz1 + bz2 + bz3 - bcz;\n"
864 gezelter 868 "\n"
865     " #if(ROTATE)\n"
866     " #local pAx_new = rotatePointX + A11 * (pAx-rotatePointX) + A12 * (pAy-rotatePointY) + A13 * (pAz-rotatePointZ);\n"
867     " #local pAy_new = rotatePointY + A21 * (pAx-rotatePointX) + A22 * (pAy-rotatePointY) + A23 * (pAz-rotatePointZ);\n"
868     " #local pAz_new = rotatePointZ + A31 * (pAx-rotatePointX) + A32 * (pAy-rotatePointY) + A33 * (pAz-rotatePointZ);\n"
869 mmeineke 629 "\n"
870 gezelter 868 " #local pBx_new = rotatePointX + A11 * (pBx-rotatePointX) + A12 * (pBy-rotatePointY) + A13 * (pBz-rotatePointZ);\n"
871     " #local pBy_new = rotatePointY + A21 * (pBx-rotatePointX) + A22 * (pBy-rotatePointY) + A23 * (pBz-rotatePointZ);\n"
872     " #local pBz_new = rotatePointZ + A31 * (pBx-rotatePointX) + A32 * (pBy-rotatePointY) + A33 * (pBz-rotatePointZ);\n"
873     "\n"
874     " #local pCx_new = rotatePointX + A11 * (pCx-rotatePointX) + A12 * (pCy-rotatePointY) + A13 * (pCz-rotatePointZ);\n"
875     " #local pCy_new = rotatePointY + A21 * (pCx-rotatePointX) + A22 * (pCy-rotatePointY) + A23 * (pCz-rotatePointZ);\n"
876     " #local pCz_new = rotatePointZ + A31 * (pCx-rotatePointX) + A32 * (pCy-rotatePointY) + A33 * (pCz-rotatePointZ);\n"
877     "\n"
878     " #local pDx_new = rotatePointX + A11 * (pDx-rotatePointX) + A12 * (pDy-rotatePointY) + A13 * (pDz-rotatePointZ);\n"
879     " #local pDy_new = rotatePointY + A21 * (pDx-rotatePointX) + A22 * (pDy-rotatePointY) + A23 * (pDz-rotatePointZ);\n"
880     " #local pDz_new = rotatePointZ + A31 * (pDx-rotatePointX) + A32 * (pDy-rotatePointY) + A33 * (pDz-rotatePointZ);\n"
881     "\n"
882     " #local pEx_new = rotatePointX + A11 * (pEx-rotatePointX) + A12 * (pEy-rotatePointY) + A13 * (pEz-rotatePointZ);\n"
883     " #local pEy_new = rotatePointY + A21 * (pEx-rotatePointX) + A22 * (pEy-rotatePointY) + A23 * (pEz-rotatePointZ);\n"
884     " #local pEz_new = rotatePointZ + A31 * (pEx-rotatePointX) + A32 * (pEy-rotatePointY) + A33 * (pEz-rotatePointZ);\n"
885     "\n"
886     " #local pFx_new = rotatePointX + A11 * (pFx-rotatePointX) + A12 * (pFy-rotatePointY) + A13 * (pFz-rotatePointZ);\n"
887     " #local pFy_new = rotatePointY + A21 * (pFx-rotatePointX) + A22 * (pFy-rotatePointY) + A23 * (pFz-rotatePointZ);\n"
888     " #local pFz_new = rotatePointZ + A31 * (pFx-rotatePointX) + A32 * (pFy-rotatePointY) + A33 * (pFz-rotatePointZ);\n"
889     "\n"
890     " #local pGx_new = rotatePointX + A11 * (pGx-rotatePointX) + A12 * (pGy-rotatePointY) + A13 * (pGz-rotatePointZ);\n"
891     " #local pGy_new = rotatePointY + A21 * (pGx-rotatePointX) + A22 * (pGy-rotatePointY) + A23 * (pGz-rotatePointZ);\n"
892     " #local pGz_new = rotatePointZ + A31 * (pGx-rotatePointX) + A32 * (pGy-rotatePointY) + A33 * (pGz-rotatePointZ);\n"
893     "\n"
894     " #local pHx_new = rotatePointX + A11 * (pHx-rotatePointX) + A12 * (pHy-rotatePointY) + A13 * (pHz-rotatePointZ);\n"
895     " #local pHy_new = rotatePointY + A21 * (pHx-rotatePointX) + A22 * (pHy-rotatePointY) + A23 * (pHz-rotatePointZ);\n"
896     " #local pHz_new = rotatePointZ + A31 * (pHx-rotatePointX) + A32 * (pHy-rotatePointY) + A33 * (pHz-rotatePointZ);\n"
897     "\n"
898     " #else\n"
899     " #local pAx_new = pAx;"
900     " #local pAy_new = pAy;"
901     " #local pAz_new = pAz;"
902     "\n"
903     " #local pBx_new = pBx;"
904     " #local pBy_new = pBy;"
905     " #local pBz_new = pBz;"
906     "\n"
907     " #local pCx_new = pCx;"
908     " #local pCy_new = pCy;"
909     " #local pCz_new = pCz;"
910     "\n"
911     " #local pDx_new = pDx;"
912     " #local pDy_new = pDy;"
913     " #local pDz_new = pDz;"
914     "\n"
915     " #local pEx_new = pEx;"
916     " #local pEy_new = pEy;"
917     " #local pEz_new = pEz;"
918     "\n"
919     " #local pFx_new = pFx;"
920     " #local pFy_new = pFy;"
921     " #local pFz_new = pFz;"
922     "\n"
923     " #local pGx_new = pGx;"
924     " #local pGy_new = pGy;"
925     " #local pGz_new = pGz;"
926     "\n"
927     " #local pHx_new = pHx;"
928     " #local pHy_new = pHy;"
929     " #local pHz_new = pHz;"
930     "\n"
931     " #end\n"
932     " #local pAx = pAx_new;"
933     " #local pAy = pAy_new;"
934     " #local pAz = pAz_new;"
935     "\n"
936     " #local pBx = pBx_new;"
937     " #local pBy = pBy_new;"
938     " #local pBz = pBz_new;"
939     "\n"
940     " #local pCx = pCx_new;"
941     " #local pCy = pCy_new;"
942     " #local pCz = pCz_new;"
943     "\n"
944     " #local pDx = pDx_new;"
945     " #local pDy = pDy_new;"
946     " #local pDz = pDz_new;"
947     "\n"
948     " #local pEx = pEx_new;"
949     " #local pEy = pEy_new;"
950     " #local pEz = pEz_new;"
951     "\n"
952     " #local pFx = pFx_new;"
953     " #local pFy = pFy_new;"
954     " #local pFz = pFz_new;"
955     "\n"
956     " #local pGx = pGx_new;"
957     " #local pGy = pGy_new;"
958     " #local pGz = pGz_new;"
959     "\n"
960     " #local pHx = pHx_new;"
961     " #local pHy = pHy_new;"
962     " #local pHz = pHz_new;"
963     "\n"
964 mmeineke 515 " #local colorR = 0.90;\n"
965     " #local colorG = 0.91;\n"
966     " #local colorB = 0.98;\n"
967     "\n"
968     " #local pipeWidth = 0.4;\n"
969     "\n"
970     " // 1\n"
971     " cylinder{\n"
972 gezelter 625 " < pAx, pAy, pAz >,\n"
973     " < pBx, pBy, pBz >,\n"
974 mmeineke 515 " pipeWidth\n"
975     " texture{\n"
976     " pigment{ rgb < colorR, colorG, colorB > }\n"
977     " finish{\n"
978     " ambient .2\n"
979     " diffuse .6\n"
980     " specular 1\n"
981     " roughness .001\n"
982     " metallic\n"
983     " }\n"
984     " }\n"
985     " }\n"
986     "\n"
987     " // 2\n"
988     " cylinder{\n"
989 gezelter 625 " < pAx, pAy, pAz >,\n"
990     " < pCx, pCy, pCz >,\n"
991 mmeineke 515 " pipeWidth\n"
992     " texture{\n"
993     " pigment{ rgb < colorR, colorG, colorB > }\n"
994     " finish{\n"
995     " ambient .2\n"
996     " diffuse .6\n"
997     " specular 1\n"
998     " roughness .001\n"
999     " metallic\n"
1000     " }\n"
1001     " }\n"
1002     " }\n"
1003     "\n"
1004     " // 3\n"
1005     " cylinder{\n"
1006 gezelter 625 " < pAx, pAy, pAz >,\n"
1007     " < pDx, pDy, pDz >,\n"
1008 mmeineke 515 " pipeWidth\n"
1009     " texture{\n"
1010     " pigment{ rgb < colorR, colorG, colorB > }\n"
1011     " finish{\n"
1012     " ambient .2\n"
1013     " diffuse .6\n"
1014     " specular 1\n"
1015     " roughness .001\n"
1016     " metallic\n"
1017     " }\n"
1018     " }\n"
1019     " }\n"
1020     "\n"
1021     " // 4\n"
1022     " cylinder{\n"
1023 gezelter 625 " < pBx, pBy, pBz >,\n"
1024     " < pEx, pEy, pEz >,\n"
1025 mmeineke 515 " pipeWidth\n"
1026     " texture{\n"
1027     " pigment{ rgb < colorR, colorG, colorB > }\n"
1028     " finish{\n"
1029     " ambient .2\n"
1030     " diffuse .6\n"
1031     " specular 1\n"
1032     " roughness .001\n"
1033     " metallic\n"
1034     " }\n"
1035     " }\n"
1036     " }\n"
1037     "\n"
1038     " // 5\n"
1039     " cylinder{\n"
1040 gezelter 625 " < pCx, pCy, pCz >,\n"
1041     " < pEx, pEy, pEz >,\n"
1042 mmeineke 515 " pipeWidth\n"
1043     " texture{\n"
1044     " pigment{ rgb < colorR, colorG, colorB > }\n"
1045     " finish{\n"
1046     " ambient .2\n"
1047     " diffuse .6\n"
1048     " specular 1\n"
1049     " roughness .001\n"
1050     " metallic\n"
1051     " }\n"
1052     " }\n"
1053     " }\n"
1054     "\n"
1055     " // 6\n"
1056     " cylinder{\n"
1057 gezelter 625 " < pBx, pBy, pBz >,\n"
1058     " < pFx, pFy, pFz >,\n"
1059 mmeineke 515 " pipeWidth\n"
1060     " texture{\n"
1061     " pigment{ rgb < colorR, colorG, colorB > }\n"
1062     " finish{\n"
1063     " ambient .2\n"
1064     " diffuse .6\n"
1065     " specular 1\n"
1066     " roughness .001\n"
1067     " metallic\n"
1068     " }\n"
1069     " }\n"
1070     " }\n"
1071     "\n"
1072     " // 7\n"
1073     " cylinder{\n"
1074 gezelter 625 " < pCx, pCy, pCz >,\n"
1075     " < pGx, pGy, pGz >,\n"
1076 mmeineke 515 " pipeWidth\n"
1077     " texture{\n"
1078     " pigment{ rgb < colorR, colorG, colorB > }\n"
1079     " finish{\n"
1080     " ambient .2\n"
1081     " diffuse .6\n"
1082     " specular 1\n"
1083     " roughness .001\n"
1084     " metallic\n"
1085     " }\n"
1086     " }\n"
1087     " }\n"
1088     "\n"
1089     " // 8\n"
1090     " cylinder{\n"
1091 gezelter 625 " < pDx, pDy, pDz >,\n"
1092     " < pGx, pGy, pGz >,\n"
1093 mmeineke 515 " pipeWidth\n"
1094     " texture{\n"
1095     " pigment{ rgb < colorR, colorG, colorB > }\n"
1096     " finish{\n"
1097     " ambient .2\n"
1098     " diffuse .6\n"
1099     " specular 1\n"
1100     " roughness .001\n"
1101     " metallic\n"
1102     " }\n"
1103     " }\n"
1104     " }\n"
1105     "\n"
1106     " // 9\n"
1107     " cylinder{\n"
1108 gezelter 625 " < pDx, pDy, pDz >,\n"
1109     " < pFx, pFy, pFz >,\n"
1110 mmeineke 515 " pipeWidth\n"
1111     " texture{\n"
1112     " pigment{ rgb < colorR, colorG, colorB > }\n"
1113     " finish{\n"
1114     " ambient .2\n"
1115     " diffuse .6\n"
1116     " specular 1\n"
1117     " roughness .001\n"
1118     " metallic\n"
1119     " }\n"
1120     " }\n"
1121     " }\n"
1122     "\n"
1123     " // 10\n"
1124     " cylinder{\n"
1125 gezelter 625 " < pEx, pEy, pEz >,\n"
1126     " < pHx, pHy, pHz >,\n"
1127 mmeineke 515 " pipeWidth\n"
1128     " texture{\n"
1129     " pigment{ rgb < colorR, colorG, colorB > }\n"
1130     " finish{\n"
1131     " ambient .2\n"
1132     " diffuse .6\n"
1133     " specular 1\n"
1134     " roughness .001\n"
1135     " metallic\n"
1136     " }\n"
1137     " }\n"
1138     " }\n"
1139     "\n"
1140     " // 11\n"
1141     " cylinder{\n"
1142 gezelter 625 " < pFx, pFy, pFz >,\n"
1143     " < pHx, pHy, pHz >,\n"
1144 mmeineke 515 " pipeWidth\n"
1145     " texture{\n"
1146     " pigment{ rgb < colorR, colorG, colorB > }\n"
1147     " finish{\n"
1148     " ambient .2\n"
1149     " diffuse .6\n"
1150     " specular 1\n"
1151     " roughness .001\n"
1152     " metallic\n"
1153     " }\n"
1154     " }\n"
1155     " }\n"
1156     "\n"
1157     " // 12\n"
1158     " cylinder{\n"
1159 gezelter 625 " < pGx, pGy, pGz >,\n"
1160     " < pHx, pHy, pHz >,\n"
1161 mmeineke 515 " pipeWidth\n"
1162     " texture{\n"
1163     " pigment{ rgb < colorR, colorG, colorB > }\n"
1164     " finish{\n"
1165     " ambient .2\n"
1166     " diffuse .6\n"
1167     " specular 1\n"
1168     " roughness .001\n"
1169     " metallic\n"
1170     " }\n"
1171     " }\n"
1172     " }\n"
1173     "\n"
1174     "#end\n"
1175     "\n"
1176 mmeineke 60 "\n");
1177 mmeineke 515
1178    
1179    
1180    
1181 mmeineke 60 make_header_macros(out_file);
1182    
1183     fclose(out_file);
1184     }
1185    
1186     return 0;
1187    
1188     }
1189    
1190    
1191    
1192     /***************************************************************************
1193     * prints out the usage for the command line arguments, then exits.
1194     ***************************************************************************/
1195    
1196     void usage(){
1197     (void)fprintf(stderr,
1198     "The proper usage is: %s [options] <xyz_file>\n"
1199     "\n"
1200     "Options:\n"
1201     "\n"
1202     " -o <prefix> the output file prefix\n"
1203     " -H generate a pov-ray header file\n"
1204     " -i <#> number of frames to interpolate\n"
1205     " -h draw hydrogens\n"
1206     " -b draw bonds\n"
1207     " -a draw atoms\n"
1208 gezelter 864 " -v draw vectors\n"
1209 mmeineke 515 " -p draw periodic box\n"
1210 mmeineke 508 " -r regenerate bond\n"
1211 mmeineke 515 " -f <#> render frame <#> only\n"
1212     " -s <#> begin at frame <#> (inclusive)\n"
1213     " -e <#> end at frame <#> (inclusive)\n"
1214 mmeineke 60 "\n",
1215     program_name);
1216     exit(8);
1217     }
1218 gezelter 864
1219     int count_tokens(line, delimiters)
1220     /* PURPOSE: RETURN A COUNT OF THE NUMBER OF TOKENS ON THE LINE. */
1221     char *line; /* LINE CONTAINING TOKENS. */
1222     char *delimiters; /* POSSIBLE TOKEN DELIMITERS TO USE. */
1223     {
1224     char *working_line; /* WORKING COPY OF LINE. */
1225     int ntokens; /* NUMBER OF TOKENS FOUND IN LINE. */
1226     char *strtok_ptr; /* POINTER FOR STRTOK. */
1227    
1228     strtok_ptr= working_line= strdup(line);
1229    
1230     ntokens=0;
1231     while (strtok(strtok_ptr,delimiters)!=NULL)
1232     {
1233     ntokens++;
1234     strtok_ptr=NULL;
1235     }
1236    
1237     free(working_line);
1238     return(ntokens);
1239     }