ls.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. /*******************************************************************************
  2. * Example source code for using the argtable3 library to implement:
  3. *
  4. * ls [-aAbBcCdDfFgGhHiklLmnNopqQrRsStuUvxX1] [--author]
  5. * [--block-size=SIZE] [--color=[WHEN]] [--format=WORD] [--full-time]
  6. * [--si] [--dereference-command-line-symlink-to-dir] [--indicator-style=WORD]
  7. * [-I PATTERN] [--show-control-chars] [--quoting-style=WORD] [--sort=WORD]
  8. * [--time=WORD] [--time-style=STYLE] [-T COLS] [-w COLS] [--help]
  9. * [--version] [FILE]...
  10. *
  11. * This file is part of the argtable3 library.
  12. *
  13. * Copyright (C) 1998-2001,2003-2011,2013 Stewart Heitmann
  14. * <sheitmann@users.sourceforge.net>
  15. * All rights reserved.
  16. *
  17. * Redistribution and use in source and binary forms, with or without
  18. * modification, are permitted provided that the following conditions are met:
  19. * * Redistributions of source code must retain the above copyright
  20. * notice, this list of conditions and the following disclaimer.
  21. * * Redistributions in binary form must reproduce the above copyright
  22. * notice, this list of conditions and the following disclaimer in the
  23. * documentation and/or other materials provided with the distribution.
  24. * * Neither the name of STEWART HEITMANN nor the names of its contributors
  25. * may be used to endorse or promote products derived from this software
  26. * without specific prior written permission.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  29. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  30. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  31. * ARE DISCLAIMED. IN NO EVENT SHALL STEWART HEITMANN BE LIABLE FOR ANY DIRECT,
  32. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  33. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  34. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  35. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  36. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  37. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. ******************************************************************************/
  39. #include "argtable3.h"
  40. /* These variables hold the values parsed from the comand line by arg_parse() */
  41. struct arg_lit *a, *A, *author, *b, *B, *c, *C, *d, *D, *f, *F, *fulltime;
  42. struct arg_lit *g, *G, *h, *H, *si, *deref, *i, *k, *l, *L, *m, *n, *N, *o, *p;
  43. struct arg_lit *q, *shcont, *Q, *r, *R, *s, *S, *t, *u, *U, *v, *x, *X, *one;
  44. struct arg_lit *help, *version;
  45. struct arg_int *blocksize, *T, *w;
  46. struct arg_str *color, *format, *indic, *I, *Qstyle, *sort, *Time, *timesty;
  47. struct arg_file *files;
  48. struct arg_end *end;
  49. /* Here we simply echo the command line option values as a demonstration. */
  50. /* In a real program, this is where we would perform the main processing. */
  51. int mymain(void)
  52. {
  53. int j;
  54. if (a->count > 0)
  55. printf("a=YES\n");
  56. if (A->count > 0)
  57. printf("A=YES\n");
  58. if (author->count > 0)
  59. printf("author=YES\n");
  60. if (b->count > 0)
  61. printf("b=YES\n");
  62. if (blocksize->count > 0)
  63. printf("blocksize=%d\n",blocksize->count);
  64. if (B->count > 0)
  65. printf("B=YES\n");
  66. if (c->count > 0)
  67. printf("c=YES\n");
  68. if (C->count > 0)
  69. printf("C=YES\n");
  70. if (color->count > 0)
  71. printf("color=%s\n",color->sval[0]);
  72. if (d->count > 0)
  73. printf("d=YES\n");
  74. if (D->count > 0)
  75. printf("D=YES\n");
  76. if (f->count > 0)
  77. printf("f=YES\n");
  78. if (F->count > 0)
  79. printf("F=YES\n");
  80. if (format->count > 0)
  81. printf("format=%s\n",format->sval[0]);
  82. if (fulltime->count > 0)
  83. printf("fulltime=YES\n");
  84. if (g->count > 0)
  85. printf("g=YES\n");
  86. if (G->count > 0)
  87. printf("G=YES\n");
  88. if (h->count > 0)
  89. printf("h=YES\n");
  90. if (si->count > 0)
  91. printf("si=YES\n");
  92. if (H->count > 0)
  93. printf("H=YES\n");
  94. if (deref->count > 0)
  95. printf("deref=YES\n");
  96. if (indic->count > 0)
  97. printf("indic=%s\n",indic->sval[0]);
  98. if (i->count > 0)
  99. printf("i=YES\n");
  100. if (I->count > 0)
  101. printf("I=%s\n",I->sval[0]);
  102. if (k->count > 0)
  103. printf("k=YES\n");
  104. if (l->count > 0)
  105. printf("l=YES\n");
  106. if (L->count > 0)
  107. printf("L=YES\n");
  108. if (m->count > 0)
  109. printf("m=YES\n");
  110. if (n->count > 0)
  111. printf("n=YES\n");
  112. if (N->count > 0)
  113. printf("N=YES\n");
  114. if (o->count > 0)
  115. printf("o=YES\n");
  116. if (p->count > 0)
  117. printf("p=YES\n");
  118. if (q->count > 0)
  119. printf("q=YES\n");
  120. if (shcont->count > 0)
  121. printf("shcont=YES\n");
  122. if (Q->count > 0)
  123. printf("Q=YES\n");
  124. if (Qstyle->count > 0)
  125. printf("Qstyle=%s\n",Qstyle->sval[0]);
  126. if (r->count > 0)
  127. printf("r=YES\n");
  128. if (R->count > 0)
  129. printf("R=YES\n");
  130. if (s->count > 0)
  131. printf("s=YES\n");
  132. if (S->count > 0)
  133. printf("S=YES\n");
  134. if (sort->count > 0)
  135. printf("sort=%s\n",sort->sval[0]);
  136. if (Time->count > 0)
  137. printf("time=%s\n",Time->sval[0]);
  138. if (timesty->count > 0)
  139. printf("timesty=%s\n",timesty->sval[0]);
  140. if (t->count > 0)
  141. printf("t=YES\n");
  142. if (T->count > 0)
  143. printf("T=%d\n",T->ival[0]);
  144. if (u->count > 0)
  145. printf("u=YES\n");
  146. if (U->count > 0)
  147. printf("U=YES\n");
  148. if (v->count > 0)
  149. printf("v=YES\n");
  150. if (w->count > 0)
  151. printf("w=%d\n",w->ival[0]);
  152. if (x->count > 0)
  153. printf("x=YES\n");
  154. if (X->count > 0)
  155. printf("X=YES\n");
  156. if (one->count > 0)
  157. printf("1=YES\n");
  158. /* print the filenames */
  159. for (j=0; j<files->count; j++)
  160. printf("filename[%d] = \"%s\"\n", j, files->filename[j]);
  161. return 0;
  162. }
  163. int main(int argc, char **argv)
  164. {
  165. /* The argtable[] entries define the command line options */
  166. void *argtable[] = {
  167. a = arg_lit0("a", "all", "do not hide entries starting with ."),
  168. A = arg_lit0("A", "almost-all", "do not list implied . and .."),
  169. author = arg_lit0(NULL,"author", "print the author of each file"),
  170. b = arg_lit0("b", "escape", "print octal escapes for nongraphic characters"),
  171. blocksize = arg_int0(NULL,"block-size","SIZE", "use SIZE-byte blocks"),
  172. B = arg_lit0("B", "ignore-backups", "do not list implied entries ending with ~"),
  173. c = arg_lit0("c", NULL, "with -lt: sort by, and show, ctime (time of last"),
  174. arg_rem(NULL, " modification of file status information)"),
  175. arg_rem(NULL, " with -l: show ctime and sort by name"),
  176. arg_rem(NULL, " otherwise: sort by ctime"),
  177. C = arg_lit0("C", NULL, "list entries by columns"),
  178. color = arg_str0(NULL,"color","WHEN", "control whether color is used to distinguish file"),
  179. arg_rem(NULL, " types. WHEN may be `never', `always', or `auto'"),
  180. d = arg_lit0("d", "directory", "list directory entries instead of contents,"),
  181. arg_rem(NULL, " and do not dereference symbolic links"),
  182. D = arg_lit0("D", "dired", "generate output designed for Emacs' dired mode"),
  183. f = arg_lit0("f", NULL, "do not sort, enable -aU, disable -lst"),
  184. F = arg_lit0("F", "classify", "append indicator (one of */=@|) to entries"),
  185. format = arg_str0(NULL,"format","WORD", "across -x, commas -m, horizontal -x, long -l,"),
  186. arg_rem (NULL, " single-column -1, verbose -l, vertical -C"),
  187. fulltime = arg_lit0(NULL,"full-time", "like -l --time-style=full-iso"),
  188. g = arg_lit0("g", NULL, "like -l, but do not list owner"),
  189. G = arg_lit0("G", "no-group", "inhibit display of group information"),
  190. h = arg_lit0("h", "human-readable", "print sizes in human readable format (e.g., 1K 234M 2G)"),
  191. si = arg_lit0(NULL,"si", "likewise, but use powers of 1000 not 1024"),
  192. H = arg_lit0("H", "dereference-command-line","follow symbolic links listed on the command line"),
  193. deref = arg_lit0(NULL,"dereference-command-line-symlink-to-dir","follow each command line symbolic link"),
  194. arg_rem(NULL, " that points to a directory"),
  195. indic = arg_str0(NULL,"indicator-style","WORD","append indicator with style WORD to entry names:"),
  196. arg_rem (NULL, " none (default), classify (-F), file-type (-p)"),
  197. i = arg_lit0("i", "inode", "print index number of each file"),
  198. I = arg_str0("I", "ignore","PATTERN", "do not list implied entries matching shell PATTERN"),
  199. k = arg_lit0("k", NULL, "like --block-size=1K"),
  200. l = arg_lit0("l", NULL, "use a long listing format"),
  201. L = arg_lit0("L", "dereference", "when showing file information for a symbolic"),
  202. arg_rem (NULL, " link, show information for the file the link"),
  203. arg_rem (NULL, " references rather than for the link itself"),
  204. m = arg_lit0("m", NULL, "fill width with a comma separated list of entries"),
  205. n = arg_lit0("n", "numeric-uid-gid", "like -l, but list numeric UIDs and GIDs"),
  206. N = arg_lit0("N", "literal", "print raw entry names (don't treat e.g. control"),
  207. arg_rem (NULL, " characters specially)"),
  208. o = arg_lit0("o", NULL, "like -l, but do not list group information"),
  209. p = arg_lit0("p", "file-type", "append indicator (one of /=@|) to entries"),
  210. q = arg_lit0("q", "hide-control-chars", "print ? instead of non graphic characters"),
  211. shcont = arg_lit0(NULL,"show-control-chars", "show non graphic characters as-is (default"),
  212. arg_rem (NULL, "unless program is `ls' and output is a terminal)"),
  213. Q = arg_lit0("Q", "quote-name", "enclose entry names in double quotes"),
  214. Qstyle = arg_str0(NULL,"quoting-style","WORD","use quoting style WORD for entry names:"),
  215. arg_rem (NULL, " literal, locale, shell, shell-always, c, escape"),
  216. r = arg_lit0("r", "reverse", "reverse order while sorting"),
  217. R = arg_lit0("R", "recursive", "list subdirectories recursively"),
  218. s = arg_lit0("s", "size", "print size of each file, in blocks"),
  219. S = arg_lit0("S", NULL, "sort by file size"),
  220. sort = arg_str0(NULL,"sort","WORD", "extension -X, none -U, size -S, time -t, version -v,"),
  221. arg_rem (NULL, "status -c, time -t, atime -u, access -u, use -u"),
  222. Time = arg_str0(NULL,"time","WORD", "show time as WORD instead of modification time:"),
  223. arg_rem (NULL, " atime, access, use, ctime or status; use"),
  224. arg_rem (NULL, " specified time as sort key if --sort=time"),
  225. timesty = arg_str0(NULL, "time-style","STYLE", "show times using style STYLE:"),
  226. arg_rem (NULL, " full-iso, long-iso, iso, locale, +FORMAT"),
  227. arg_rem (NULL, "FORMAT is interpreted like `date'; if FORMAT is"),
  228. arg_rem (NULL, "FORMAT1<newline>FORMAT2, FORMAT1 applies to"),
  229. arg_rem (NULL, "non-recent files and FORMAT2 to recent files;"),
  230. arg_rem (NULL, "if STYLE is prefixed with `posix-', STYLE"),
  231. arg_rem (NULL, "takes effect only outside the POSIX locale"),
  232. t = arg_lit0("t", NULL, "sort by modification time"),
  233. T = arg_int0("T", "tabsize", "COLS", "assume tab stops at each COLS instead of 8"),
  234. u = arg_lit0("u", NULL, "with -lt: sort by, and show, access time"),
  235. arg_rem (NULL, " with -l: show access time and sort by name"),
  236. arg_rem (NULL, " otherwise: sort by access time"),
  237. U = arg_lit0("U", NULL, "do not sort; list entries in directory order"),
  238. v = arg_lit0("v", NULL, "sort by version"),
  239. w = arg_int0("w", "width", "COLS", "assume screen width instead of current value"),
  240. x = arg_lit0("x", NULL, "list entries by lines instead of by columns"),
  241. X = arg_lit0("X", NULL, "sort alphabetically by entry extension"),
  242. one = arg_lit0("1", NULL, "list one file per line"),
  243. help = arg_lit0(NULL,"help", "display this help and exit"),
  244. version = arg_lit0(NULL,"version", "display version information and exit"),
  245. files = arg_filen(NULL, NULL, "FILE", 0, argc+2, NULL),
  246. end = arg_end(20),
  247. };
  248. const char *progname = "ls";
  249. int exitcode=0;
  250. int nerrors;
  251. /* verify the argtable[] entries were allocated sucessfully */
  252. if (arg_nullcheck(argtable) != 0)
  253. {
  254. /* NULL entries were detected, some allocations must have failed */
  255. printf("%s: insufficient memory\n",progname);
  256. exitcode=1;
  257. goto exit;
  258. }
  259. /* allow optional argument values for --color */
  260. /* and set the default value to "always" */
  261. color->hdr.flag |= ARG_HASOPTVALUE;
  262. color->sval[0] = "always";
  263. /* Parse the command line as defined by argtable[] */
  264. nerrors = arg_parse(argc,argv,argtable);
  265. /* special case: '--help' takes precedence over error reporting */
  266. if (help->count > 0)
  267. {
  268. printf("Usage: %s", progname);
  269. arg_print_syntax(stdout,argtable,"\n");
  270. printf("List information about the FILE(s) (the current directory by default).\n");
  271. printf("Sort entries alphabetically if none of -cftuSUX nor --sort.\n\n");
  272. arg_print_glossary(stdout,argtable," %-25s %s\n");
  273. printf("\nSIZE may be (or may be an integer optionally followed by) one of following:\n"
  274. "kB 1000, K 1024, MB 1,000,000, M 1,048,576, and so on for G, T, P, E, Z, Y.\n\n"
  275. "By default, color is not used to distinguish types of files. That is\n"
  276. "equivalent to using --color=none. Using the --color option without the\n"
  277. "optional WHEN argument is equivalent to using --color=always. With\n"
  278. "--color=auto, color codes are output only if standard output is connected\n"
  279. "to a terminal (tty).\n\n"
  280. "Report bugs to <foo@bar>.\n");
  281. exitcode=0;
  282. goto exit;
  283. }
  284. /* special case: '--version' takes precedence error reporting */
  285. if (version->count > 0)
  286. {
  287. printf("'%s' example program for the \"argtable\" command line argument parser.\n",progname);
  288. printf("September 2003, Stewart Heitmann\n");
  289. exitcode=0;
  290. goto exit;
  291. }
  292. /* If the parser returned any errors then display them and exit */
  293. if (nerrors > 0)
  294. {
  295. /* Display the error details contained in the arg_end struct.*/
  296. arg_print_errors(stdout,end,progname);
  297. printf("Try '%s --help' for more information.\n",progname);
  298. exitcode=1;
  299. goto exit;
  300. }
  301. /* Command line parsing is complete, do the main processing */
  302. exitcode = mymain();
  303. exit:
  304. /* deallocate each non-null entry in argtable[] */
  305. arg_freetable(argtable,sizeof(argtable)/sizeof(argtable[0]));
  306. return exitcode;
  307. }