home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 2001 January / VPR0101A.BIN / OLS / ZIP3J036 / zip3j036.lzh / zip32j / SRC / ZIP32J / CMDLINE.C next >
C/C++ Source or Header  |  2000-10-29  |  5KB  |  234 lines

  1. /*
  2.     cmdline.c
  3.         by Yoshioka Tsuneo(QWF00133@niftyserve.or.jp)
  4.         welcome any e-mail!!
  5.         You can use this file as Public Domain Software.
  6.         Copy,Edit,Re-distibute and for any purpose,you can use this file.
  7. */
  8. #include "cmdline.h"
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #include <ctype.h>
  12. #include <stdio.h>
  13. #include <sys/types.h>
  14. #include <sys/stat.h>
  15.  
  16. /* 多分記号は全部0x40未満だからうまくいくだろう・・・ */
  17. #define KANJI
  18.  
  19. #ifdef KANJI
  20. #define UCH(c)  ((unsigned char)(c))
  21. #define iskanji1(c) ((0x81<=UCH(c)&&UCH(c)<=0x9F)||(0xE0<=UCH(c)&&UCH(c)<=0xFC))
  22. #define iskanji2(c) ((0x40<=UCH(c)&&UCH(c)<=0x7E)||(0x80<=UCH(c)&&UCH(c)<=0xFC))
  23. #endif
  24. /* ptr の配列の長さを求める(NULLポインタが終端) */
  25. int ptrarraylen(void  **ptr)
  26. {
  27.     int len=0;
  28.     while(*ptr++){
  29.         len++;
  30.     }
  31.     return len;
  32. }
  33. /* 文字列の(ポインタの)配列をまるごとコピー(複製)する */
  34. /* 一列にまとめることで一回freeを呼ぶだけで配列まるごと開放できる*/
  35. /* strarray[0] strarray[1] strarray[2] NULL *strarray[0] *strarray[1] *strarray[2] */
  36. char **strarraydup(char **strarray)
  37. {
  38.     char **files_dup=NULL;
  39.     int filenum;
  40.     int alllen;
  41.     int i;
  42.     char *ptr;
  43.  
  44.     filenum=ptrarraylen(strarray);
  45.     alllen=0;
  46.     for(i=0;i<filenum;i++){
  47.         alllen=alllen+strlen(strarray[i])+1;
  48.     }
  49.     if((files_dup=malloc(sizeof(char*)*(filenum+1)+alllen))==NULL)goto endlabel;
  50.     ptr=(char *)files_dup+sizeof(char*)*(filenum+1);
  51.     for(i=0;i<filenum;i++){
  52.         strcpy(ptr,strarray[i]);
  53.         files_dup[i]=ptr;
  54.         ptr=ptr+strlen(ptr)+1;
  55.     }
  56.     files_dup[i]=NULL;
  57.  
  58. endlabel:
  59.     /* free memory */
  60.     /*    not free here!
  61.     for(i=0;i<filenum;i++){
  62.         free(files[i]);
  63.     }
  64.     free(files);
  65.     */
  66.     return files_dup;
  67. }
  68. /*    コマンドライン引数を分割する
  69.     (レスポンスファイルは利用しない。)*/
  70. char ** split_cmdline(char *cmdline)
  71. {
  72.     char *ptr=cmdline;
  73.     char *oldpt=ptr;
  74.     char **files=NULL;
  75.     char **files2=NULL;
  76.     char *file;
  77.     int filelen=0;
  78.     int filelen2=0;
  79.     char *filep;
  80.     int quote_mode=0;
  81.     int filenum=0;
  82.     int i;
  83.  
  84.     while(isspace((unsigned char)*ptr)){ptr++;}
  85.     while(*ptr){
  86.         filelen2=4096;
  87.         filelen=0;
  88.         if((file=malloc(filelen2))==NULL){
  89.             goto endlabel;
  90.         }
  91.         filep=file;
  92.         while(((!isspace((unsigned char)*ptr)) || quote_mode) && *ptr!='\0'){
  93.             if(*ptr=='"'){
  94.                 quote_mode = !quote_mode;
  95.                 ptr++;
  96.             }else{
  97.                 if(filelen>=filelen2-5){
  98.                     filelen2+=4096;
  99.                     if((realloc2(&file,filelen2))==NULL) goto endlabel;
  100.                     filep=file+filelen;
  101.                 }
  102. #ifdef KANJI
  103.                 /* if 2 byte charactor then copy on more byte */
  104.                 if(iskanji1(*ptr) && iskanji2(*(ptr+1))){
  105.                     *filep++=*ptr++;
  106.                     filelen+=1;
  107.                 }
  108. #endif
  109.                 *filep++=*ptr++;
  110.                 filelen+=1;
  111.             }
  112.         }
  113.         *filep='\0';
  114.         /*if((p=malloc(sizeof(char)*(strlen(file)+1)))==NULL)
  115.             goto errorlabel;
  116.         strcpy(p,file);*/
  117.         if(realloc2(&files,sizeof(char *)*(filenum+1))==NULL){
  118.             free(file);
  119.             goto endlabel;
  120.         }
  121.         filenum++;
  122.         files[filenum-1]=file;
  123.         while(isspace((unsigned char)*ptr)){
  124.             ptr++;
  125.         }
  126.     }
  127.     if(realloc2(&files,sizeof(char *)*(filenum+1))==NULL){
  128.         free(file);
  129.         goto endlabel;
  130.     }
  131.     files[filenum]=NULL;
  132.     files2=strarraydup(files);
  133.  
  134. endlabel:
  135.     if(files!=NULL){
  136.         for(i=0;i<filenum;i++){
  137.             free(files[i]);
  138.         }
  139.         free(files);
  140.     }
  141.     return files2;    
  142. }
  143.  
  144. /*ファイルを読み込んで文字列に入れる*/
  145. char *loadfile(char *fname)
  146. {
  147.     FILE *fp;
  148.     char *filebody=NULL;
  149.     int l;
  150.     struct stat buf;
  151.     int size;
  152.  
  153.     if(stat(fname,&buf)!=0){return NULL;}
  154.     size=buf.st_size;
  155.     
  156.     if((fp=fopen(fname,"rb"))==NULL){
  157.         return NULL;
  158.     }
  159.     if((filebody=malloc(size+1))==NULL){fclose(fp);return NULL;}
  160.     l=fread(filebody,1,size,fp);
  161.     fclose(fp);
  162.     if(l!=size){
  163.         free(filebody);
  164.         return NULL;
  165.     }
  166.     filebody[size]='\0';
  167.     return filebody;
  168. }
  169.  
  170. /* reallocを呼んで返り値を*ptrに入れる (NULLの場合は入れない)*/
  171. void *realloc2(void **ptr,int size)
  172. {
  173.     void *ret;
  174.     ret=realloc(*ptr,size);
  175.     if(ret!=NULL){
  176.         *ptr=ret;
  177.     }
  178.     return ret;
  179. }
  180.  
  181. /* コマンドラインを展開 */
  182. /*  @ではじまるレスポンスファイルがあればそれも展開する。*/
  183. char **split_cmdline_with_response(char *cmdline)
  184. {
  185.     char **files=NULL;
  186.     char **files2;
  187.     char **files3=NULL;
  188.     char ***files4=NULL;
  189.     char **files5=NULL;
  190.     int files4count=0;
  191.     int files3count=0;
  192.  
  193.     if((files=split_cmdline(cmdline))==NULL){
  194.         return -1;
  195.     }
  196.     files2=files;
  197.  
  198.  
  199.     while(*files2!=NULL){
  200.         if(**files2=='@'){
  201.             char *filebody;
  202.             char **ptrptr;
  203.             if((filebody=loadfile(*files2+1))==NULL)goto endlabel;
  204.             if(realloc2(&files4,(files4count+1)*sizeof(char *))==NULL)goto endlabel;
  205.             files4count++;
  206.             if((ptrptr=split_cmdline(filebody))==NULL)goto endlabel;
  207.             files4[files4count-1]=ptrptr;
  208.             free(filebody);
  209.             while(*ptrptr!=NULL){
  210.                 if(realloc2(&files3,(files3count+1)*sizeof(char *))==NULL)goto endlabel;
  211.                 files3[files3count]=*ptrptr++;
  212.                 files3count++;
  213.             }
  214.             files2++;
  215.         }else{
  216.             if(realloc2(&files3,(files3count+1)*sizeof(char *))==NULL)goto endlabel;
  217.             files3[files3count]=*files2++;
  218.             files3count++;
  219.         }
  220.     }
  221.     if(realloc2(&files3,(files3count+1)*sizeof(char *))==NULL)goto endlabel;
  222.     files3[files3count]=NULL;
  223.     if((files5=strarraydup(files3))==NULL) goto endlabel;
  224. endlabel:
  225.     if(files!=NULL)free(files);
  226.     if(files3!=NULL)free(files3);
  227.     if(files4!=NULL){
  228.         int i;
  229.         for(i=0;i<files4count;i++) free(files4[i]);
  230.         free(files4);
  231.     }
  232.     return files5;
  233. }
  234.