/usr.bin/colrm/colrm.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 142 lines · 97 code · 16 blank · 29 comment · 22 complexity · 879238a847d46052ba5fc3e9afe0a5ce MD5 · raw file

  1. /*-
  2. * Copyright (c) 1991, 1993
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 4. Neither the name of the University nor the names of its contributors
  14. * may be used to endorse or promote products derived from this software
  15. * without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  21. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. */
  29. #ifndef lint
  30. static const char copyright[] =
  31. "@(#) Copyright (c) 1991, 1993\n\
  32. The Regents of the University of California. All rights reserved.\n";
  33. #endif
  34. #if 0
  35. #ifndef lint
  36. static char sccsid[] = "@(#)colrm.c 8.2 (Berkeley) 5/4/95";
  37. #endif
  38. #endif
  39. #include <sys/cdefs.h>
  40. __FBSDID("$FreeBSD$");
  41. #include <sys/types.h>
  42. #include <err.h>
  43. #include <errno.h>
  44. #include <limits.h>
  45. #include <locale.h>
  46. #include <stdio.h>
  47. #include <stdlib.h>
  48. #include <string.h>
  49. #include <unistd.h>
  50. #include <wchar.h>
  51. #define TAB 8
  52. void check(FILE *);
  53. static void usage(void);
  54. int
  55. main(int argc, char *argv[])
  56. {
  57. u_long column, start, stop;
  58. int ch, width;
  59. char *p;
  60. setlocale(LC_ALL, "");
  61. while ((ch = getopt(argc, argv, "")) != -1)
  62. switch(ch) {
  63. case '?':
  64. default:
  65. usage();
  66. }
  67. argc -= optind;
  68. argv += optind;
  69. start = stop = 0;
  70. switch(argc) {
  71. case 2:
  72. stop = strtol(argv[1], &p, 10);
  73. if (stop <= 0 || *p)
  74. errx(1, "illegal column -- %s", argv[1]);
  75. /* FALLTHROUGH */
  76. case 1:
  77. start = strtol(argv[0], &p, 10);
  78. if (start <= 0 || *p)
  79. errx(1, "illegal column -- %s", argv[0]);
  80. break;
  81. case 0:
  82. break;
  83. default:
  84. usage();
  85. }
  86. if (stop && start > stop)
  87. errx(1, "illegal start and stop columns");
  88. for (column = 0;;) {
  89. switch (ch = getwchar()) {
  90. case WEOF:
  91. check(stdin);
  92. break;
  93. case '\b':
  94. if (column)
  95. --column;
  96. break;
  97. case '\n':
  98. column = 0;
  99. break;
  100. case '\t':
  101. column = (column + TAB) & ~(TAB - 1);
  102. break;
  103. default:
  104. if ((width = wcwidth(ch)) > 0)
  105. column += width;
  106. break;
  107. }
  108. if ((!start || column < start || (stop && column > stop)) &&
  109. putwchar(ch) == WEOF)
  110. check(stdout);
  111. }
  112. }
  113. void
  114. check(FILE *stream)
  115. {
  116. if (feof(stream))
  117. exit(0);
  118. if (ferror(stream))
  119. err(1, "%s", stream == stdin ? "stdin" : "stdout");
  120. }
  121. void
  122. usage(void)
  123. {
  124. (void)fprintf(stderr, "usage: colrm [start [stop]]\n");
  125. exit(1);
  126. }