home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast.iso / dv_x / dvxhlp10.zip / MDVXHELP.C < prev    next >
C/C++ Source or Header  |  1992-06-03  |  9KB  |  330 lines

  1. /*
  2.  *   MDVXHELP - A utility to create DV/X Help Files
  3.  *
  4.  *   Copyright 1992 by Daniel J. Bodoh
  5.  *
  6.  *   File: mdvxhelp.c
  7.  *
  8.  *   Compiled with Turbo C 2.0
  9.  *
  10.  *   History:
  11.  *      28-MAY-92   DJB   Created
  12.  *      29-MAY-92   DJB   Modified to replace single \n\r's with spaces
  13.  *                        BUG FIX: buffer index not rezerod in process_section()
  14.  *
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <dir.h>
  20. #include <string.h>
  21. #include <mem.h>
  22.  
  23. #include "mdvxhelp.h"
  24.  
  25.  
  26. /* Globals */
  27. unsigned long curoff=0;     /* current offset into output file */
  28. Header header={0,0};        /* File header */
  29. Tag *first_tag=NULL;        /* Head of tag list */
  30. Dir_elem *directory;
  31. char outfile[MAXPATH];     /* out file name */
  32.                             /* Head of directory list */
  33. FILE *ofp;                  /* output file */
  34.  
  35. char ifile[MAXFILES][MAXPATH];      /* input filenames */
  36. int numfiles=0;
  37.  
  38. int main(int argc, char *argv[]) {
  39.     int i;
  40.     char ext[MAXEXT];
  41.     char tmp[MAXPATH];
  42.     Tag *t;
  43.     int xpm;
  44.     FILE *fp;
  45.  
  46.     if (argc<3) {
  47.         /* print out help screen */
  48.         printf("MDVXHELP %s Copyright 1992 by Daniel J. Bodoh\n",VERSION);
  49.         printf("\nusage: mdvxhelp <output-file> <section-file ...> [<icon-file ...>]\n");
  50.         printf("     or: mdvxhelp <output-file> @<list-file>\n");
  51.  
  52.         exit(0);
  53.     }
  54.  
  55.     strcpy(outfile,argv[1]);
  56.     /* open the output file */
  57.     if ((ofp=fopen(outfile,"wb"))==NULL) {
  58.         fprintf(stderr,"Cannot %s for output\n",argv[1]);
  59.         exit(1);
  60.     }
  61.  
  62.     if (argv[2][0]=='@') {
  63.         /* list file */
  64.         if ((fp=fopen(argv[2]+1,"r"))==NULL) {
  65.             err_exit("Could not open list file\n");
  66.         }
  67.         i=0;
  68.         while (fgets(tmp,sizeof tmp,fp)!=NULL) {
  69.             sscanf(tmp,"%s",ifile[i]);
  70.             if (i++>=MAXFILES) {
  71.                 fprintf(stderr,"Warning: more than %d input files; extra ignored\n",MAXFILES);
  72.                 i=MAXFILES;
  73.                 break;
  74.             }
  75.         }
  76.         numfiles=i;
  77.         fclose(fp);
  78.     }
  79.     else {
  80.         /* read files from command line */
  81.         numfiles = argc-2;
  82.         if (numfiles>MAXFILES) {
  83.             numfiles=MAXFILES;
  84.             fprintf(stderr,"Warning: more than %d input files; extra ignored\n",MAXFILES);
  85.         }
  86.         for (i=0;i<numfiles;i++) {
  87.             strcpy(ifile[i],argv[i+2]);
  88.         }
  89.     }
  90.  
  91.  
  92.     /* create directory array */
  93.     header.dir_size=(numfiles+3)*sizeof(Dir_elem);
  94.     directory = (Dir_elem *)malloc(header.dir_size);
  95.     if (directory==NULL) err_exit("Out of memory");
  96.     memset(directory,0,header.dir_size);
  97.  
  98.     /* write the header immediately; update later */
  99.     if (fwrite(&header,sizeof header,(size_t)1,ofp)<1) {
  100.         err_exit("Error writing to file");
  101.     }
  102.     curoff += sizeof header;
  103.  
  104.     xpm=0;
  105.     for (i=0;i<numfiles;i++) {
  106.         /* fill a directory entry */
  107.         /* what's the extension? */
  108.         fnsplit(ifile[i],NULL,NULL,NULL,ext);
  109.         strupr(ext);
  110.         if (strcmp(ext,".XPM")==0) {
  111.             if (!xpm) {
  112.                 /* before the icons, write out the tags */
  113.                 /* create BKCOVER dir entry */
  114.                 create_dir_entry("BKCOVER",curoff,i+1);
  115.                 /* write out tags */
  116.                 fputs("/CCblue/\n\r",ofp);
  117.                 curoff += 10;
  118.                 t = first_tag;
  119.                 while (t!=NULL) {
  120.                     fputs(t->tagstr,ofp);
  121.                     curoff += strlen(t->tagstr);
  122.                     t=t->flink;
  123.                 }
  124.                 fputc(0x1A,ofp);
  125.                 curoff += 1;
  126.                 xpm=1;
  127.             }
  128.             create_dir_entry(ifile[i],curoff,i+2);
  129.             process_xpm(ifile[i]);
  130.         }
  131.         else {
  132.             create_dir_entry(ifile[i],curoff,i+1);
  133.             process_section(ifile[i]);
  134.         }
  135.     }
  136.  
  137.     /* put file together */
  138.     if (!xpm) {
  139.         /* if no icons were written, we have to write the tags */
  140.         /* create BKCOVER dir entry */
  141.         create_dir_entry("BKCOVER",curoff,numfiles+1);
  142.         /* write out tags */
  143.         fputs("/CCblue/\r\n",ofp);
  144.         curoff += 10;
  145.         t = first_tag;
  146.         while (t!=NULL) {
  147.             fputs(t->tagstr,ofp);
  148.             curoff += strlen(t->tagstr);
  149.             t=t->flink;
  150.         }
  151.         fputc(0x1A,ofp);
  152.         curoff += 1;
  153.     }
  154.  
  155.     header.dir_off=curoff;
  156.  
  157.     create_dir_entry(NULL,curoff,0);
  158.     /* write the directory */
  159.     if (fwrite(directory,header.dir_size,1,ofp)<1) {
  160.         err_exit("Error writing to file");
  161.     }
  162.     rewind(ofp);
  163.     /* update header */
  164.     if (fwrite(&header,sizeof header,(size_t)1,ofp)<1) {
  165.         err_exit("Error writing to file");
  166.     }
  167.  
  168.  
  169.     fclose(ofp);
  170.     exit(0);
  171. }
  172.  
  173. void err_exit(char *msg) {
  174.     /* Writes msg to stderr; deletes output file; exits */
  175.     fprintf(stderr,"%s\n",msg);
  176.     fclose(ofp);
  177.     unlink(outfile);
  178.     exit(1);
  179. }
  180.  
  181. void process_section(char *file) {
  182.     /* Reads in a section file; processes it and writes to outfile */
  183.     FILE *fp;
  184.     char msg[80];
  185.     static char ibuf[BUFFER_SIZE];
  186.     static char obuf[BUFFER_SIZE];
  187.     size_t cnt;
  188.     long i, j;
  189.     char h[2];
  190.  
  191.     if ((fp=fopen(file,"rb"))==NULL) {
  192.         sprintf(msg,"Cannot open %s",file);
  193.         err_exit(msg);
  194.     }
  195.  
  196.     printf("Adding section %s...",file);
  197.  
  198.     h[0]=fgetc(fp);
  199.     if (h[0]=='$') {
  200.         /* the first and second lines contains a tag.  Let's read it in */
  201.         fgets(ibuf,sizeof ibuf,fp);
  202.         fgets(obuf,sizeof obuf,fp);
  203.         strcat(ibuf,obuf);
  204.         create_tag(ibuf);
  205.         printf("Tag attached...\n");
  206.     }
  207.     else {
  208.         ungetc(h[0],fp);
  209.         printf("\n");
  210.     }
  211.  
  212.     cnt = fread(ibuf, 1, sizeof ibuf, fp);
  213.  
  214.     h[0]=h[1]=0;
  215.  
  216.     while (cnt!=0) {
  217.         j=0;
  218.         for (i=0;i<cnt;i++) {
  219.             /* skip single \r\n's but don't skip double...*/
  220.             if (ibuf[i]=='\r' || ibuf[i]=='\n') {
  221.                 if ((h[0]=='\r' && h[1]=='\n')||(h[0]=='\n' && h[1]=='\r')) {
  222.                     obuf[j++]='\n';
  223.                     obuf[j++]='\r';
  224.                     i++;    /* jump over next char, assume is \r or \n */
  225.                     h[0]=h[1]=0;
  226.                 }
  227.                 else {
  228.                     h[0]=h[1];
  229.                     h[1]=ibuf[i];
  230.                 }
  231.             }
  232.             else {
  233.                 /* replace \n\r with a space */
  234.                 if ((h[0]=='\r' && h[1]=='\n')||(h[0]=='\n' && h[1]=='\r')) {
  235.                     obuf[j++]=' ';
  236.                 }
  237.                 h[0]=h[1];
  238.                 h[1]=ibuf[i];
  239.                 obuf[j++]=ibuf[i];
  240.             }
  241.  
  242.         }
  243.         if (fwrite(obuf,1,j,ofp)<j) {
  244.             err_exit("Error writing to file");
  245.         }
  246.         curoff += j;
  247.         cnt = fread(ibuf,1, sizeof ibuf, fp);
  248.     }
  249.     fputc(0x1A,ofp); /* section separator */
  250.     curoff += 1;
  251.     fclose(fp);
  252. }
  253.  
  254. void process_xpm(char *file) {
  255.     /* Reads in an XPM and writes to outfile */
  256.     FILE *fp;
  257.     char msg[80];
  258.     static char ibuf[BUFFER_SIZE];
  259.     size_t cnt;
  260.  
  261.     if ((fp=fopen(file,"rb"))==NULL) {
  262.         sprintf(msg,"Cannot open %s",file);
  263.         err_exit(msg);
  264.     }
  265.  
  266.     printf("Adding icon %s...\n",file);
  267.  
  268.     cnt = fread(ibuf, 1, sizeof ibuf, fp);
  269.  
  270.     while (cnt!=0) {
  271.         if (fwrite(ibuf,1,cnt,ofp)<cnt) {
  272.             err_exit("Error writing to file");
  273.         }
  274.         curoff += cnt;
  275.         cnt = fread(ibuf, 1, sizeof ibuf, fp);
  276.     }
  277.     fclose(fp);
  278. }
  279.  
  280. void create_dir_entry(char *path, long offset, int i) {
  281.     char file[MAXFILE], ext[MAXEXT];
  282.  
  283.     fnsplit(path,NULL,NULL,file,ext);
  284.     switch(i) {
  285.         case 0:
  286.             /* this is directory */
  287.             strcpy(directory[i].sect_name,"directory");
  288.             break;
  289.         case 1:
  290.             /* this is FRCOVER */
  291.             strcpy(directory[i].sect_name,"FRCOVER");
  292.             break;
  293.         case 2:
  294.             strcpy(directory[i].sect_name,"CONTENTS");
  295.             break;
  296.         default:
  297.             strcpy(directory[i].sect_name,file);
  298.             strcat(directory[i].sect_name,ext);
  299.             break;
  300.     }
  301.  
  302.     directory[i].offset=offset;
  303. }
  304.  
  305. void create_tag(char *tagtxt) {
  306.     Tag *p;
  307.  
  308.     /* traverse the current list */
  309.     p = first_tag;
  310.  
  311.     if (p!=NULL) {
  312.         while (p->flink!=NULL) p=p->flink;
  313.         if ((p->flink=(Tag *)malloc(sizeof(Dir_elem)))==NULL) {
  314.             err_exit("Out of memory");
  315.         }
  316.         p=p->flink;
  317.     }
  318.     else {
  319.         if ((first_tag=(Tag *)malloc(sizeof(Dir_elem)))==NULL) {
  320.             err_exit("Out of memory");
  321.         }
  322.         p=first_tag;
  323.     }
  324.     if ((p->tagstr=(char *)malloc(strlen(tagtxt)+1))==NULL) {
  325.         err_exit("Out of memory");
  326.     }
  327.     strcpy(p->tagstr,tagtxt);
  328.     p->flink=NULL;
  329. }
  330.