home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 2003 November / VPR0311.ISO / OLS / TAR32223 / tar32223.lzh / tar32_2 / src / Cmdline.c < prev    next >
C/C++ Source or Header  |  2003-01-17  |  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. #ifdef WIN32
  18. #define KANJI
  19. #endif
  20.  
  21.  
  22. #ifdef KANJI
  23. #define UCH(c)  ((unsigned char)(c))
  24. #define iskanji1(c) ((0x81<=UCH(c)&&UCH(c)<=0x9F)||(0xE0<=UCH(c)&&UCH(c)<=0xFC))
  25. #define iskanji2(c) ((0x40<=UCH(c)&&UCH(c)<=0x7E)||(0x80<=UCH(c)&&UCH(c)<=0xFC))
  26. #endif
  27. /* ptr の配列の長さを求める(NULLポインタが終端) */
  28. int ptrarraylen(void  **ptr)
  29. {
  30.     int len=0;
  31.     while(*ptr++){
  32.         len++;
  33.     }
  34.     return len;
  35. }
  36. /* 文字列の(ポインタの)配列をまるごとコピー(複製)する */
  37. /* 一列にまとめることで一回freeを呼ぶだけで配列まるごと開放できる*/
  38. /* strarray[0] strarray[1] strarray[2] NULL *strarray[0] *strarray[1] *strarray[2] */
  39. char **strarraydup(char **strarray)
  40. {
  41.     char **files_dup=NULL;
  42.     int filenum;
  43.     int alllen;
  44.     int i;
  45.     char *ptr;
  46.  
  47.     filenum=ptrarraylen((void**)strarray);
  48.     alllen=0;
  49.     for(i=0;i<filenum;i++){
  50.         alllen=alllen+strlen(strarray[i])+1;
  51.     }
  52.     if((files_dup=malloc(sizeof(char*)*(filenum+1)+alllen))==NULL)goto endlabel;
  53.     ptr=(char *)files_dup+sizeof(char*)*(filenum+1);
  54.     for(i=0;i<filenum;i++){
  55.         strcpy(ptr,strarray[i]);
  56.         files_dup[i]=ptr;
  57.         ptr=ptr+strlen(ptr)+1;
  58.     }
  59.     files_dup[i]=NULL;
  60. endlabel:
  61.     /* free memory */
  62.     /*    not free here!
  63.     for(i=0;i<filenum;i++){
  64.         free(files[i]);
  65.     }
  66.     free(files);
  67.     */
  68.     return files_dup;
  69. }
  70. /*    コマンドライン引数を分割する
  71.     (レスポンスファイルは利用しない。)*/
  72. char ** split_cmdline(const char *cmdline)
  73. {
  74.     const char *ptr=cmdline;
  75.     const char *oldpt=ptr;
  76.     char **files=NULL;
  77.     char **files2=NULL;
  78.     char *file;
  79.     int filelen=0;
  80.     int filelen2=0;
  81.     char *filep;
  82.     int quote_mode=0;
  83.     int filenum=0;
  84.     int i;
  85.  
  86.     while(isspace((unsigned char)*ptr)){ptr++;}
  87.     while(*ptr){
  88.         filelen2=4096;
  89.         filelen=0;
  90.         if((file=malloc(filelen2))==NULL){
  91.             goto endlabel;
  92.         }
  93.         filep=file;
  94.         while(((!isspace((unsigned char)*ptr)) || quote_mode) && *ptr!='\0'){
  95.             if(*ptr=='"'){
  96.                 quote_mode = !quote_mode;
  97.                 ptr++;
  98.             }else{
  99.                 if(filelen>=filelen2-5){
  100.                     filelen2+=4096;
  101.                     if((realloc2((void**)&file,filelen2))==NULL) goto endlabel;
  102.                     filep=file+filelen;
  103.                 }
  104. #ifdef KANJI
  105.                 /* if 2 byte charactor then copy on more byte */
  106.                 if(iskanji1(*ptr) && iskanji2(*(ptr+1))){
  107.                     *filep++=*ptr++;
  108.                     filelen+=1;
  109.                 }
  110. #endif
  111.                 *filep++=*ptr++;
  112.                 filelen+=1;
  113.             }
  114.         }
  115.         *filep='\0';
  116.         /*if((p=malloc(sizeof(char)*(strlen(file)+1)))==NULL)
  117.             goto errorlabel;
  118.         strcpy(p,file);*/
  119.         if(realloc2((void**)&files,sizeof(char *)*(filenum+1))==NULL){
  120.             free(file);
  121.             goto endlabel;
  122.         }
  123.         filenum++;
  124.         files[filenum-1]=file;
  125.         while(isspace((unsigned char)*ptr)){ptr++;}
  126.     }
  127.     if(realloc2((void**)&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(const 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 NULL;
  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((void**)&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((void**)&files3,(files3count+1)*sizeof(char *))==NULL)goto endlabel;
  211.                 files3[files3count]=*ptrptr++;
  212.                 files3count++;
  213.             }
  214.             files2++;
  215.         }else{
  216.             if(realloc2((void**)&files3,(files3count+1)*sizeof(char *))==NULL)goto endlabel;
  217.             files3[files3count]=*files2++;
  218.             files3count++;
  219.         }
  220.     }
  221.     if(realloc2((void**)&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.