Command-line processor

di il
9 risposte

Command-line processor

Ho scritto nel mio poco tempo a disposizione, un po' di fretta, un command-line parser da integrare in un altro progetto che sto scrivendo sempre a tempo perso.
Se (non sentitevi in obbligo) qualcuno se la sente di testarlo (a tempo perso) segnalandomi bug(s) ve ne sarei grato.

Saluti,
Max

/**
 *  Copyright (C) 2011, Max Cavallo <ixamit_at_gmail_dot_com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *

  opt process a command-line. Every option has long and short form. 
  mix and join different option styles like:
    opt -bcd
    opt -b -c -d
    opt --background -c --debug
    opt -c--debug --background
    ...
    opt ARGV -olog
    opt ARGV -o log
    opt --log-file=log ARGV
    opt ARGV --log-file = log
    ...
    opt --execute-command:system -db argv1 --tries  20
    opt --tries='20' -dbe system argv1
    ...
    opt -bcd -t 3 --dns-timeout=10 --retry-connrefused -o log localhost -e dir

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#ifdef _WIN32
#ifndef snprintf
#define snprintf _snprintf
#endif
#endif

#define countof(x) (sizeof (x) / sizeof ((x)[0]))
#define OPT_SPACE     '\40'
#define OPT_SEPARATOR '\43'//'\35'

#define OPT_UNRECOGNIZED_OPTION "unrecognized option"
#define OPT_REQUIRED_ARGUMENT   "option requires an argument"
#define OPT_INVALID_PARAMETER   "invalid parameter"
#define OPT_INVALID_ASSIGNEMENT "invalid assignement"
#define OPT_OUT_OF_MEMORY        "out of memory"
            
static struct _opt_var *opt_first_var=NULL;
static struct _opt_var *opt_last_var =NULL;

void print_help ();

struct _opt_var
{
  char *key;
  char *value;
  struct _opt_var *next;
};
struct _opt
{
  /**
    long && short names are refered to option name witch called 
    from the command line. prefix are respectivly '--' & '-'
  */
  char *long_name;
  char short_name;              
  
  /**
    assignement char per value. It is used by enum type.
    refered to OPT_ASSIGN
  */
  #define OPT_ASSIGN "= :\0"
  enum {
    opt_equal,
    opt_space,
    opt_colon,
    opt_null,   
  } assign;
  
  /**
    meaning 'type_of_data'.
    opt_bool     == boolean (assign == opt_null)
    opt_value    == numeric (assign == opt_equal | opt_space | opt_colon)
    opt_string   == alpha   (assign == opt_equal | opt_space | opt_colon)
    opt_callback == function pointer callback (opt_null)
  */
  enum {
    opt_callback,
    opt_bool,
    opt_value,
    opt_string,
  } type;
  
  /**
    real name for option witch you referenced or function pointer callback
  */
  void *data;
  
  /**
    short help descriptive
    -used only for automatic helper-
  */
  char *hlp_des;
  
  /**
    extra argument assignement help, ie:
    {"tries",'t' ...... "number"} 
    it will show:
    -t, --tries=number ......
    -used only for automatic helper-
  */
  char *hlp_arg;

};


/**
  =============================================
  put your options arguments here; you need it!
  =============================================
*/
#define OPT_PRG_NAME "test"
static char opt_synopsis[]="Usage: " OPT_PRG_NAME " [option]... [argv]...";
static struct _opt opt_options[]=
{
  {"help",'h',opt_null,opt_callback,(void *)print_help,"Print this help",NULL}, 
  {"background",'b',opt_null,opt_bool,"background","Go to background immediately after startup",NULL},
  {"color",'c',opt_null,opt_bool,"color","Change color",NULL},
  {"debug",'d',opt_null,opt_bool,"debug","Turn on debug output",NULL},
  {"tries",'t',opt_equal,opt_value,"tries","Set number of retries to number","number"}, 
  {"dns-timeout",0,opt_equal,opt_value,"dns_timeout","Imposta il timeout per la risoluzione del DNS","SECONDI"},
  {"retry-connrefused",0,opt_null,opt_bool,"retry_connrefused","riprova anche se la connessione è rifiutata",NULL},
  {"log-file",'o',opt_equal,opt_string,"log_file","Log all messages to logfile","logfile"},  
  {"execute-command",'e',opt_colon,opt_string,"execute_command","A command thus invoked will be executed","command"},
};
/**
  =============================================
*/

/** 
  This is the automatic default help. 
  It's generated by reading the struct opt_options[]; you should easly use that function 
  or different by changing pointer in the help field declared above.
*/

void print_help ()
{
  char buff[40];
  int i,j;
  
  printf ("%s\n\n",opt_synopsis);
  for (i=0;i<countof(opt_options);i++)
  {
    snprintf (buff,sizeof(buff)," %c%c%c --%s%c%s",
              (opt_options[i].short_name==' ' || opt_options[i].short_name==0) ? ' ' : '-',
              (opt_options[i].short_name==' ' || opt_options[i].short_name==0) ? ' ' : opt_options[i].short_name,
              (opt_options[i].short_name==' ' || opt_options[i].short_name==0) ? ' ' : ',',
              opt_options[i].long_name,
              OPT_ASSIGN[opt_options[i].assign],
              opt_options[i].hlp_arg);
    printf ("%s",buff);
    for (j=strlen(buff);j<sizeof(buff);j++)
      printf (" ");
    printf ("%s\n",opt_options[i].hlp_des);
  }
  printf ("\n");
}

/**
  dump data to stream
*/
void opt_out (FILE *stream,char *p, int n)
{
  for (;n;n--)
    fprintf (stream,"%c",*(p++));
}

/**
  This is init function. 
  It return an allocated opt string with all argv separated by OPT_SEPARATOR
  ie:  foo bar 'foo bar' ---> foo#bar#foo bar\0
  return word's number or error
*/
int opt_init (int argc,char **argv,char **opt)
{
  int i,err=0,l=0,wc=argc-1;

  opt_first_var=opt_last_var=NULL;
  *opt=NULL;
  
  /** possibly incongruences type assignement */
  for (i=0;!err && i<countof(opt_options);i++)
  {
    switch (opt_options[i].type)
    {
      case opt_callback:
        if (opt_options[i].assign != opt_null)
          err=opt_options[i].type+1;
        break;
      case opt_bool:
        if (opt_options[i].assign != opt_null)
          err=opt_options[i].type+1;
        break;       
      case opt_value:
        if (opt_options[i].assign != opt_equal && 
            opt_options[i].assign != opt_space &&
            opt_options[i].assign != opt_colon)
          err=opt_options[i].type+1;
        break;
      case opt_string:
        if (opt_options[i].assign != opt_equal && 
            opt_options[i].assign != opt_space &&
            opt_options[i].assign != opt_colon)
          err=opt_options[i].type+1;
        break;       
    }
  }
  if (err)
  {
    fprintf (stderr,"opt_init::opt_options[%d] "OPT_INVALID_ASSIGNEMENT"\n",i);
    return -1;
  }
  
  /**
    TODO more fields control
  */
    
  if (wc)
  {
    for (--argc;argc>0;argc--)
      l+=strlen(argv[argc]);
    
    l+=(wc-1);
    if ((*opt=malloc(l+1))==NULL)
    {
      fprintf (stderr, OPT_OUT_OF_MEMORY"\n");
      return -1;
    }  
    memset (*opt,OPT_SEPARATOR,l); (*opt)[l]='\0';
    
    for (i=0,argc=1;argc<=wc;argc++)
    {
      l=strlen(argv[argc]);
      memcpy (*opt+i,argv[argc],l);
      i+=(l+1);
    }
  }
  
  return (wc);
}

/**
  Just save the key && the value into a linked list.
*/
int set_opt (char *key,char *value, int l_value)
{
  struct _opt_var *node; 
  int l_key=(key) ? strlen(key): 0;
  
  node=(struct _opt_var *)malloc (sizeof(struct _opt_var));
  node->key=(l_key) ? (char *) malloc (l_key+1) : (char *)0;
  node->value=(l_value) ? (char *) malloc (l_value+1) : (char *)0;
  if (!node)
  {
    if (node->value)    free (node->value);
    if (node->key)      free (node->key);
    if (node)           free (node);
    fprintf (stderr,OPT_OUT_OF_MEMORY"\n");
    return -1;
  }
  if (l_key)
    memcpy (node->key, key,l_key+1);
  if (l_value)
  {
    memcpy (node->value,  value, l_value);
    node->value[l_value]='\0';
  }

  node->next=NULL;
  if (!opt_first_var)   opt_first_var=node;
  if (opt_last_var)     opt_last_var->next=node;
  opt_last_var=node;
  
  return 0;
}

/**
  Search opt[ion] in opt_options[]
*/
int opt_search_short (char opt)
{
  int i;
  for (i=0;i<countof(opt_options);i++)
    if (opt_options[i].short_name==opt)
      return i;
    
  fprintf (stderr,OPT_UNRECOGNIZED_OPTION " '-%c'\n",opt);
  return -1;
}
/**
  Search opt[ion] in opt_options[]
*/
int opt_search_long (char *opt)
{
  char *end;
  int i,l;
  
  for (i=0;i<countof(opt_options);i++)
  {
    l=strlen(opt_options[i].long_name);
    if ((strncmp (opt_options[i].long_name,opt,l))==0)
    {
      if (opt[l]==OPT_SEPARATOR || strchr(OPT_ASSIGN,(int)opt[l]))
        return i;
    }
  }
  for (l=0,end=opt;*end && *end!=OPT_SEPARATOR;end++,l++);
  fprintf (stderr,OPT_UNRECOGNIZED_OPTION " '--");
  opt_out (stderr,opt,l);
  printf ("'\n");
  return -1;
}

/**
  Main parsing option_line. 
*/
int opt_index (char *options_line)
{
  char *opt=options_line,*key,*value;
  int is_option,is_option_long, is_option_short;
  int i,index,l_value=0,err=0;
  int (*checkfunc) (int)=NULL;
  
  if (!opt)
    err=-1;
  
  is_option=is_option_long=is_option_short=0;
  while (!err && *opt)
  {
    /**
      init flags 
      removing prefix dash
    */
    index=0; key=value=NULL; l_value=0;
    if (*opt==OPT_SEPARATOR) {is_option=is_option_long=is_option_short=0;opt++;}
    if (*opt=='-') {is_option=1;is_option_short=1;is_option_long=0;opt++;}
    if (*opt=='-') {is_option_long=1;is_option_short=0;opt++;}   


    /** option is short */
    if (is_option_short)
    {
      if ((index=opt_search_short (*opt))>=0)
      {
        key=(char *)opt_options[index].data;
        /** move next argument */
        for (++opt;*opt && (*opt==OPT_SEPARATOR || *opt==OPT_SPACE);opt++);
      }
      else
      {
        /** unrecognized short option */
        err=-1;
        break;
      }
    }
    
    /** option is long */
    if (is_option_long)
    {
      if ((index=opt_search_long (opt))>=0)
      {
        key=(char *)opt_options[index].data;
        /** move next argument */
        opt+=strlen(opt_options[index].long_name);
        for (;*opt && (*opt==OPT_SEPARATOR || *opt==OPT_SPACE);opt++);
        if (*opt && *opt==OPT_ASSIGN[opt_options[index].assign])
          for (opt++;*opt && (*opt==OPT_SEPARATOR || *opt==OPT_SPACE);opt++);
      }
      else
      {
        /** unrecognized long option */
        err=-1;
        break;
      }
    }

    /** execute callback function */
    if (is_option && opt_options[index].type==opt_callback)
    {
      void (*func) (void) = (void (*) (void)) opt_options[index].data;
      func ();
      continue;
    }

    /** getting value || ARGV */
    if (  !is_option                           ||
          opt_options[index].type==opt_value   || 
          opt_options[index].type==opt_string    )
    {
      value=opt;
      for (l_value=0;*opt && *opt!=OPT_SEPARATOR;opt++,l_value++);
    }
      
    /** check 4 value */  
    if (is_option && value)
    {
      if (l_value==0)
      {
        fprintf (stderr,"\'%s\' "OPT_REQUIRED_ARGUMENT"\n",opt_options[index].long_name);
        err=-1;
        break;
      }
      switch (opt_options[index].type)
      {
        case opt_string:
          checkfunc=isprint;
          break;
        case opt_value:
          checkfunc=isdigit;
          break;
        default:
          break;
      }
      if (opt_options[index].type!=opt_callback)
      {
        for (i=0;i<l_value;i++)
        {
          if (checkfunc(value[i])==0)
          {
            fprintf (stderr,"\'--%s\' "OPT_INVALID_PARAMETER" \"",opt_options[index].long_name);
            opt_out (stderr,value,l_value);
            printf ("\"\n");
            err=-1;
            break;
          }    
        }
      }
    }
    
    if (!err)
    {
      err=set_opt (key,value, l_value);
    }
    if (value==NULL && *(opt-1)==OPT_SEPARATOR) opt--;
  }
 
  return err;
}

/**
  Get the ARGC parsed
*/
int opt_get_argc ()
{
  struct _opt_var *p;
  int argc;
  for (argc=0,p=opt_first_var;p;p=p->next)
    if (!p->key) argc++;
  return argc;
}
/**
  Get the ARGV[n] parsed
  return value || NULL
*/
char *opt_get_argv (int n)
{
  struct _opt_var *p;
  int argc;
  for (argc=0,p=opt_first_var;p;p=p->next)
  {
    if (!p->key)
    {
      if (argc++==n)  return (p->value);
    }
  }
  return NULL;
}

/**
  Get the option
  key=field (char *)data in opt_options[]
  return:
    NULL no_key found
    (char *) to saved value
*/
char *opt_get (char *key)
{
  struct _opt_var *p;
  for (p=opt_first_var;p;p=p->next)
  {
    if ((p->key) && (strcmp(p->key,key)==0))
    {
      return (p->value) ? p->value : "1";
    }
  }
  return NULL;
}

/**
  free all memory
  (all but not opt)
*/
void opt_free ()
{
  struct _opt_var *p,*next=NULL;
  for (p=opt_first_var;p;p=next)
  {
    if (p->key)     free (p->key);
    if (p->value)   free (p->value);
    next=p->next;
    free (p);
    
  }
}

/**
  just the opt_test;
  dumping some values
*/
void opt_test ()
{
  struct _opt_var *p;
  int i,argc;
  
  printf ("OPTIONS:\n");
  if (!opt_first_var) printf ("[none]\n");
  for (p=opt_first_var;p;p=p->next)
    if (p->key)
      printf ("%s=%s\n",(p->key)?p->key:"ARGV",p->value); 
  printf ("\n");
  
  argc=opt_get_argc();
  printf ("THERE %s %d ARGC\n",(argc==1)?"IS":"ARE",argc);
  if (!argc) printf ("[none]\n");
  for (i=0;i<argc;i++)
    printf ("ARGV[%d]=%s\n",i,opt_get_argv(i));
  printf ("\n");

  printf ("CAN EASILY SET YOUR ENVIROMENT:\n");
  printf ("background=%s\n",opt_get("background"));
  printf ("color=%s\n",opt_get("color"));
  printf ("debug=%s\n",opt_get("debug"));
  printf ("tries=%s\n",opt_get("tries"));
  printf ("log_file=%s\n",opt_get("log_file"));
  printf ("execute_command=%s\n",opt_get("execute_command"));
  printf ("retry_connrefused=%s\n",opt_get("retry_connrefused"));
  printf ("dns_timeout=%s\n",opt_get("dns_timeout"));

}

int main (int argc,char **argv)
{
  char *options_line;
  int err=0;
  
  if (argc<2)
  {
    print_help ();
    return -1;
  }
  
  /** need init opt */
  if (opt_init (argc,argv,&options_line)>0)
  {
    /** the main parser */
    if ((err=opt_index (options_line))==0)
    {
      /** free options_line */
      if (options_line) free (options_line);

      /** lets use it now */
      opt_test ();

      /** remeber to free opt enviroment */
      opt_free ();
    }
  }
  
  /** remember to check for errors */
  printf ("\nEXIT with %d\n",err);
  return err;
}

9 Risposte

  • Re: Command-line processor

    Max io ho Visual Studio senza supporto C99 percui snprintf non me la conosce. Con che cosa lo cambio?
    
    test.c(155) : warning C4013: 'snprintf' undefined; assuming extern returning int
    
    Altri warning su WALL
    
    testc(428) : warning C4701: potentially uninitialized local variable 'checkfunc' used
    test.c(578) : warning C4701: potentially uninitialized local variable 'err' used
    
  • Re: Command-line processor

    Max io ho Visual Studio senza supporto C99 percui snprintf non me la conosce. Con che cosa lo cambio?
    bella domanda... forse così?!
    
    #define snprintf _snprintf
    
    fonte:
  • Re: Command-line processor

    Ok, dimmi che devo fa Adesso compila OK.
  • Re: Command-line processor

    Alcuni esempi sono nell src
    
       ...
      opt process a command-line. Every option has long and short form. 
      mix and join different option styles like:
        opt -bcd
        opt -b -c -d
        opt --background -c --debug
        opt -c--debug --background
        ...
        opt ARGV -olog
        opt ARGV -o log
        opt --log-file=log ARGV
        opt ARGV --log-file = log
        ...
        opt --execute-command:system -db argv1 --tries  20
        opt --tries='20' -dbe system argv1
       ...
    
  • Re: Command-line processor

    
    OPTIONS:
    color=(null)
    debug=(null)
    background=(null)
    
    THERE ARE 2 ARGC
    ARGV[0]=dir
    ARGV[1]=c:\
    
    CAN EASLY SET YOUR ENVIROMENT:
    background=1
    color=1
    debug=1
    tries=(null)
    log_file=(null)
    execute_command=(null)
    
    EXIT with 0
    
    va bene?
  • Re: Command-line processor

    Dipende da quello che hai inserito. potrebbe essere qualcosa tipo:
    
           dir -cdb 'c:\ '
    
    immagina molti argomenti che possono essere passati es:
    
      -h,  --help              mostra questo aiuto.               
      -b,  --background        va in background dopo l'avvio.     
      -o,  --output-file=FILE    registra i messaggi su FILE.
      -a,  --append-output=FILE  accoda i messaggi a FILE.   
      -d,  --debug               mostra le informazioni di debug.
      -q,  --quiet               silenzioso (nessun output).     
      -v,  --verbose             prolisso (predefinito).         
      -nv, --no-verbose          meno prolisso, ma non silenzioso.
      -i,  --input-file=FILE     scarica gli URL scritti in FILE. 
      -F,  --force-html          tratta il file di input come HTML.
      -B,  --base=URL            aggiunge URL ai link relativi quando si usa -F 
                                 sul file indicato con -i.                      
      -t,  --tries=NUMERO           imposta il NUMERO di tentativi (0 = illimitati).
           --retry-connrefused      riprova anche se la connessione è rifiutata.    
      -O   --output-document=FILE   scrive tutti i documenti in un singolo FILE.    
      -nc, --no-clobber             non scaricare file già esistenti.               
      -c,  --continue               riprende a scaricare un file parzialmente       
                                    scaricato.                                      
           --progress=TIPO          sceglie il TIPO di misurazione di progresso.    
      -N,  --timestamping           non scarica file più vecchi di quelli locali.   
      -S,  --server-response        mostra le risposte del server.                  
           --spider                 non scarica niente.                             
      -T,  --timeout=SECONDI        imposta tutti i timeout a SECONDI.              
           --dns-timeout=SECONDI    imposta il timeout per la risoluzione del DNS   
                                    a SECONDI.                                      
           --connect-timeout=SECONDI imposta il timeout di connessione a SECONDI.   
           --read-timeout=SECONDI   imposta il timeout di lettura a SECONDI.        
      -w,  --wait=SECONDI           aspetta SECONDI tra i vari download.            
           --waitretry=SECONDI      aspetta 1...SECONDI tra i tentativi di          
                                    scaricamento.                                   
           --random-wait            aspetta tra 0...2*WAIT secondi tra scaricamenti.
           --no-proxy               disattiva esplicitamente l'uso del proxy.       
      -Q,  --quota=NUMERO           imposta la quota di scaricamento a NUMERO.      
           --bind-address=INDIRIZZO lega l'INDIRIZZO (nome dell'host o IP)          
                                    all'host locale.                                
           --limit-rate=VELOCITÀ    limita la VELOCITÀ di scaricamento in byte.     
           --no-dns-cache           disattiva la cache per la risoluzione del DNS.  
           --restrict-file-names=SO limita i caratteri nei nomi dei file a quelli   
                                    permessi dal sistema operativo SO indicato.     
           --ignore-case           ignora maiuscole/minuscole nei file/directory.   
      -4,  --inet4-only             si connette solo a indirizzi IPv4.              
      -6,  --inet6-only             si connette solo a indirizzi IPv6.              
           --prefer-family=FAMIGLIA  si connette di preferenza ad indirizzi della   
                                     FAMIGLIA specificata (IPv6, IPv4 o none).      
           --user=UTENTE             imposta il nome utente ftp e http a UTENTE.    
           --password=PASS           imposta la password ftp e http a PASS.         
      -nd, --no-directories           non crea directory.
      -x,  --force-directories        forza la creazione di directory.
      -nH, --no-host-directories      non crea directory sull'host.   
           --protocol-directories     usa il nome di protocollo nelle directory.
      -P,  --directory-prefix=PREFISSO   salva i file in PREFISSO/...           
           --cut-dirs=NUMERO             ignora NUMERO componenti delle directory
                                         remote.                                 
           --http-user=UTENTE      imposta l'utente http a UTENTE.
           --http-passwd=PASS      imposta la password http a PASS.
           --no-cache              non permette la cache dei dati sul server.
      -E,  --html-extension      salva con estensione ".html" i documenti HTML.
           --ignore-length       ignora il campo Content-Length nelle intestazioni.
           --header=STRINGA      inserisce STRINGA tra le intestazioni.            
           --max-redirect          massimo numero di redirezioni per pagina.       
           --proxy-user=UTENTE   imposta il nome utente per il proxy a UTENTE.     
           --proxy-passwd=PASS   imposta la password per il proxy a PASS.          
           --referer=URL         include l'intestazione "Referer: URL" nella       
                                 richiesta HTTP.                                   
           --save-headers        salva le intestazioni HTTP su file.               
      -U,  --user-agent=AGENTE   si identifica come AGENTE invece che come         
                                 VERSIONE.                                    
           --no-http-keep-alive  disabilita l'HTTP keep-alive (connessioni         
                                 persistenti).                                     
           --no-cookies            non usa i cookies.                              
           --load-cookies=FILE   carica i cookies dal FILE prima della sessione.   
           --save-cookies=FILE   salva i cookies sul FILE dopo la sessione.        
           --keep-session-cookies  carica e salva i cookies per la sessione        
                                   (non permanenti).                               
           --post-data=STRINGA   usa il metodo POST; spedisce STRINGA come dati.   
           --post-file=FILE      usa il metodo POST; spedisce i contenuti del FILE.
           --content-disposition   onora l'intestazione Content-Disposition quando 
                                   si scelgono nomi di file locali (SPERIMENTALE). 
           --auth-no-challenge     Invia informazioni di autenticazione Basic HTTP 
                                   senza prima aspettare la richiesta dal server.  
           --secure-protocol=PROT.  sceglie il protocollo sicuro, uno tra auto,
                                    SSLv2, SSLv3,e TLSv1.                      
           --no-check-certificate   non valida il certificato del server.      
           --certificate=FILE       file di certificato del client.            
           --certificate-type=TIPO  tipo di certificato del client, PEM o DER. 
           --private-key=FILE       file della chiave privata.                 
           --private-key-type=TIPO  tipo di chiave privata, PEM o DER.         
           --ca-certificate=FILE    file con il bundle dei CA.                 
           --ca-directory=DIR       directory dove è memorizzata la lista dei CA.
           --random-file=FILE       file con dati casuali per inizializzare      
                                    SSL PRNG.                                    
           --egd-file=FILE          file col nome del socket EGD con dati casuali.
           --ftp-user=UTENTE       imposta l'utente ftp a UTENTE.
           --ftp-password=PASS     imposta la password ftp a PASS.
           --no-remove-listing     non elimina i file ".listing". 
           --no-glob              disabilita il globbing FTP dei nome di file.
           --no-passive-ftp        disabilita la modalità di trasferimento passiva.
           --retr-symlinks        scarica i file (non le directory) puntati dai    
                                  link simbolici quando si è in modalità ricorsiva.
           --preserve-permissions  preserva i permessi remoti dei file.            
      -r,  --recursive          scaricamento ricorsivo.
      -l,  --level=NUMERO       profondità massima di ricorsione
                                (inf o 0 = illimitata).         
           --delete-after         elimina localmente i file dopo averli scaricati.
      -k,  --convert-links        converte i link assoluti in relativi.
      -K,  --backup-converted     salva il file X come X.orig prima di convertirlo.
      -m,  --mirror               scorciatoia per -N -r -l inf --no-remove-listing.
      -p,  --page-requisites      scarica tutte le immagini, ecc, necessarie per
                                  visualizzare la pagina HTML.
           --strict-comments      tratta i commenti HTML in modalità strict (SGML).
      -A,  --accept=LISTA                lista di estensioni accettate, separate da
                                         virgole.
      -R,  --reject=LISTA                lista di estensioni rifiutate, separate da
                                         virgole.
      -D,  --domains=LISTA               lista di domini accettati, separati da
                                         virgole.
           --exclude-domains=LISTA       lista di domini rifiutati, separati da
                                         virgole.
           --follow-ftp                  segue i link FTP dai documenti HTML.
           --follow-tags=LISTA           lista di tag HTML, separati da virgole,
                                         che vengono seguiti nello scaricamento.
           --ignore-tags=LISTA           lista di tag HTML, separati da virgole,
                                         che vengono ignorati.
      -H,  --span-hosts                  visita anche altri host quando si è in
                                         modalità ricorsiva.
      -L,  --relative                    segue solo i link relativi.
      -I,  --include-directories=LISTA   lista di directory permesse.
      -X,  --exclude-directories=LISTA   lista di directory escluse.
      -np, --no-parent                   non risale alla directory superiore.
    
    
  • Re: Command-line processor

    Ora compila con la direttiva _WIN32?
    edit:
    ho editato l' src precedente
  • Re: Command-line processor

    Si compila, nessun problema. Tolti anche gli warning precedenti.
  • Re: Command-line processor

    Grazie skynet,
    sei stato molto gentile
Devi accedere o registrarti per scrivere nel forum
9 risposte