Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π² срСдС Linux. Π’Ρ‚ΠΎΡ€ΠΎΠ΅ ΠΈΠ·Π΄Π°Π½ΠΈΠ΅Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 123

Автор Майкл ДТонсон

  1: /* grep.с */

  2:

  3: #include <alloca.h>

  4: #include <ctype.h>

  5: #include <popt.h>

  6: #include <regex.h>

  7: #include <stdio.h>

  8: #include <string.h>

  9: #include <unistd.h>

 10:

 11: #define MODE_REGEXP 1

 12: #define MODE_EXTENDED 2

 13: #define MODE_FIXED 3

 14:

 15: void do_regerror(int errcode, const regex_t *preg) {

 16:  char *errbuf;

 17:  size_t errbuf_size;

 18:

 19:  errbuf_size = regerror(errcode, preg, NULL, 0);

 20:  errbuf = alloca(errbuf_size);

 21:  if (!errbuf) {

 22:   perror("alloca");

 23:   return;

 24:  }

 25:

 26:  regerror(errcode, preg, errbuf, errbuf_size);

 27:  fprintf(stderr, "%s\n", errbuf);

 28: }

 29:

 30: int scanFile(FILE * f, int mode, const void * pattern,

 31:  int ignoreCase, const char * fileName,

 32:  int * maxCountPtr) {

 33:  long lineLength;

 34:  char * line;

 35:  int match;

 36:  int rc;

 37:  char * chptr;

 38:  char * prefix = "";

 39:

 40:  if (fileName) {

 41:   prefix = alloca(strlen(fileName) + 4);

 42:   sprintf(prefix, "%s: ", fileName);

 43:  }

 44:

 45:  lineLength = sysconf(_SC_LINE_MAX);

 46:  line = alloca(lineLength);

 47:

 48:  while (fgets(line, lineLength, f) && (*maxCountPtr)) {

 49:   /* Ссли Ρƒ нас Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‰Π΅Π³ΠΎ символа '\n'

 50:      Ρ‚ΠΎ ΠΌΡ‹ Π½Π΅ смоТСм ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ всю строку Ρ†Π΅Π»ΠΈΠΊΠΎΠΌ */

 51:   if (line [strlen (line) -1] != '\n') {

 52:    fprintf(stderr, " %s line слишком длинная\n", prefix);

 53:    return 1;

 54:   }

 55:

 56:   if (mode == MODE_FIXED) {

 57:    if (ignoreCase) {

 58:     for (chptr = line; *chptr; chptr++) {

 59:      if (isalpha(*chptr)) *chptr = tolower(*chptr);

 60:     }

 61:    }

 62:    match = (strstr(line, pattern) != NULL);

 63:   } else {

 64:    match = 0;

 65:    rc = regexec (pattern, line, 0, NULL, 0);

 66:    if (!rc)

 67:     match = 1;

 68:    else if (rc != REG_NOMATCH)

 69:    do_regerror(match, pattern);

 70:   }

 71:

 72:   if (match) {

 73:    printf("%s%s", prefix, line);

 74:    if (*maxCountPtr > 0)

 75:     (*maxCountPtr)--;

 76:   }

 77:  }

 78:

 79:  return 0;

 80: }

 81:

 82: int main(int argc, const char ** argv) {

 83:  const char * pattern = NULL;

 84:  regex_t regPattern;

 85:  const void * finalPattern;

 86:  int mode = MODE_REGEXP;

 87:  int ignoreCase = 0;

 88:  int maxCount = -1;

 89:  int rc;

 90:  int regFlags;

 91:  const char ** files;

 92:  poptContext optCon;

 93:  FILE * f;

 94:  char * chptr;

 95:  struct poptOption optionsTable[] = {

 96:   { "extended-regexp", 'E', POPT_ARG_VAL,

 97:     &mode, MODE_EXTENDED,

 98:     "шаблоном для соотвСтствия являСтся Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½Π½ΠΎΠ΅ рСгулярноС "

 99:     "Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅"},

100:   { "fixed-strings", 'F', POPT_ARG_VAL,

101:     &mode, MODE_FIXED,

102:     "шаблоном для соотвСтствия являСтся базовая строка (Π½Π΅ "

103:     "рСгулярноС Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅)", NULL },

104:   { "basic-regexp", 'G', POPT_ARG_VAL,

105:     &mode, MODE_REGEXP,

106:     "шаблоном для соотвСтствия являСтся Π±Π°Π·ΠΎΠ²ΠΎΠ΅ рСгулярноС Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅" },

107:   { "ignore-case", 'i', POPT_ARG_NONE, &ignoreCase, 0,

108:     "Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ поиск, Ρ‡ΡƒΠ²ΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΊ рСгистру", NULL },

109:   { "max-count", 'm', POPT_ARG_INT, &maxCount, 0,

110:     "Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ послС получСния N. совпадСний", "N" },

111:   { "regexp", 'e', POPT_ARG_STRING, &pattern, 0,

112:     "рСгулярноС Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ для поиска", "pattern" },

113:     POPT_AUTOHELP

114:   { NULL, '\0', POPT_ARG_NONE, NULL, 0, NULL, NULL }

115:  };

116:

117:  optCon = poptGetContext("grep", argc, argv, optionsTable, 0);

118:  poptSetOtherOptionHelp(optCon, "<шаблон> <список Ρ„Π°ΠΉΠ»ΠΎΠ²>");

119:

120:  if ((rc = poptGetNextOpt(optCon)) < -1) {

121:   /* Π²ΠΎ врСмя ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Π²ΠΎΠ·Π½ΠΈΠΊΠ»Π° ошибка */

122:   fprintf(stderr, "%s: %s\n",

123:    poptBadOption(optCon, POPT_BADOPTION_NOALIAS),

124:   poptStrerror(rc));

125:   return 1;

126:  }

127:

128:  files = poptGetArgs(optCon);

129:  /* Ссли ΠΌΡ‹ Π½Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ шаблон, Ρ‚ΠΎ ΠΎΠ½ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΠΏΠ΅Ρ€Π²Ρ‹ΠΌ

130:     ΠΈΠ· ΠΎΡΡ‚Π°Π²ΡˆΠΈΡ…ΡΡ */

131:  if (!files && !pattern) {

132:   poptPrintUsage(optCon, stdout, 0);

133:   return 1;

134:  }

135:

136:  if (!pattern) {

137:   pattern = files[0];

138:   files++;

139:  }

140:

141:  regFlags = REG_NEWLINE | REG_NOSUB;

142:  if (ignoreCase) {

143:   regFlags |= REG_ICASE;

144:   /* ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ шаблона Π² Π½ΠΈΠΆΠ½ΠΈΠΉ рСгистр; этого ΠΌΠΎΠΆΠ½ΠΎ Π½Π΅ Π΄Π΅Π»Π°Ρ‚ΡŒ,

145:      Ссли ΠΌΡ‹ ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΠ΅ΠΌ рСгистр Π² рСгулярном Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΈ, ΠΎΠ΄Π½Π°ΠΊΠΎ позволяСт

146:      Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ strstr() ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ -i */

147:   chptr = alloca(strlen(pattern) + 1);

148:   strcpy(chptr, pattern);

149:   pattern = chptr;

150:

151:   while (*chptr) {

152:    if (isalpha(*chptr)) *chptr = tolower(*chptr);

153:    chptr++;

154:   }

155:  }

156:

157:

158:  switch (mode) {

159:  case MODE_EXTENDED:

160:   regFlags |= REG_EXTENDED;

161:  case MODE_REGEXP:

162:   if ((rc = regcomp(&regPattern, pattern, regFlags))) {

163:    do_regerror(rc, &regPattern);

164:    return 1;

165:   }

166:   finalPattern = &regPattern;

167:   break;

168:

169:  case MODE_FIXED:

170:   finalPattern = pattern;

171:   break;

172:  }

173:

174:  if (!*files) {

175:   rc = scanFile(stdin, mode, finalPattern, ignoreCase, NULL,

176:    &maxCount);

177:  } else if (!files[1]) {

178:   /* эта Ρ‡Π°ΡΡ‚ΡŒ обрабатываСтся ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ имя Ρ„Π°ΠΉΠ»Π°

179:      Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ΡŒ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ */

180:   if (!(f = fopen(*files, "r"))) {

181:    perror(*files);

182:    rc = 1;

183:   } else {

184:    rc = scanFile(f, mode, finalPattern, ignoreCase, NULL,

185:     &maxCount);

186:    fclose(f);

187:   }

188:  } else {

189:   rc = 0;

190:

191:   while (*files) {

192:    if (!(f = fopen(*files, "r"))) {

193:     perror(*files);

194:     rc = 1;

195:    } else {

196:     rc |= scanFile(f, mode, finalPattern, ignoreCase,

197:      *files, &maxCount);

198:     fclose(f);

199:    }

200:    files++;

201:    if (!maxCount) break;

202:   }

203:  }

204:

205:  return rc;

206: }

Π“Π»Π°Π²Π° 24

Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π°ΠΌΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ S-Lang

Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ S-Lang, написанной Π”ΠΆΠΎΠ½ΠΎΠΌ Дэвисом (John Π•. Davis), ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡ‚ΡŒ доступ ΠΊ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π°ΠΌ Π½Π° срСднСм ΡƒΡ€ΠΎΠ²Π½Π΅. ВсС дСйствия, связанныС с ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π°ΠΌΠΈ Π½Π° Π½ΠΈΠ·ΠΊΠΎΠΌ ΡƒΡ€ΠΎΠ²Π½Π΅, ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡŽΡ‚ΡΡ посрСдством Π½Π°Π±ΠΎΡ€Π° ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ, ΠΏΡ€Π΅Π΄Π»Π°Π³Π°ΡŽΡ‰ΠΈΡ… прямой доступ ΠΊ Π²ΠΈΠ΄Π΅ΠΎΡ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π°ΠΌ ΠΈ автоматичСски ΡƒΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΠΈΡ… ΠΏΡ€ΠΎΠΊΡ€ΡƒΡ‚ΠΊΠΎΠΉ ΠΈ Ρ†Π²Π΅Ρ‚Π°ΠΌΠΈ. НСсмотря Π½Π° Π½Π΅Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΏΡ€ΡΠΌΡƒΡŽ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ ΠΎΠΊΠΎΠ½ ΠΈ отсутствиС Π² S-Lang ΠΊΠ°ΠΊΠΈΡ…-Π»ΠΈΠ±ΠΎ элСмСнтов управлСния, для Ρ‚Π°ΠΊΠΈΡ… Π·Π°Π΄Π°Ρ‡ эта Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ ΡƒΠ΄ΠΎΠ±Π½ΡƒΡŽ основу[167].

Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ S-Lang ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π² DOS, Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ Π΅Π΅ ΠΏΡ€ΠΈΠ²Π»Π΅ΠΊΠ°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΉ для создания ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ Π½Π° ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ°Ρ… Unix ΠΈ DOS.

ВозмоТности управлСния Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π°ΠΌΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ S-Lang ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚ΡŒ Π½Π° Π΄Π²Π΅ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ. Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ Π½Π°Π±ΠΎΡ€ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ для управляСмого считывания Π½Π°ΠΆΠ°Ρ‚ΠΈΠΉ клавиш ΠΈΠ· Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π°. Π’ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ…, ΠΎΠ½Π° содСрТит Π½Π°Π±ΠΎΡ€ ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ для полноэкранного Π²Ρ‹Π²ΠΎΠ΄Π° Π½Π° Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π». МногиС возмоТности Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»ΠΎΠ² Π±ΡƒΠ΄ΡƒΡ‚ нСдоступными для программистов, ΠΎΠ΄Π½Π°ΠΊΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΌΠΈ возмоТностями ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π° ΠΌΠΎΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ[168]. Π’ этой Π³Π»Π°Π²Π΅ Π²Ρ‹ ΡƒΠ·Π½Π°Π΅Ρ‚Π΅ ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ S-Lang ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊΠΎ всСм этим Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΌ возмоТностям, Π° Π² ΠΊΠΎΠ½Ρ†Π΅ Π³Π»Π°Π²Ρ‹ Π²Π°ΠΌ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ для закрСплСния ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Π°.

24.1. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π²Π²ΠΎΠ΄Π°

ΠŸΠΎΠ΄ΡΠΈΡΡ‚Π΅ΠΌΠ° управлСния Π²Π²ΠΎΠ΄ΠΎΠΌ Π½Π° Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π°Ρ… являСтся ΠΎΠ΄Π½ΠΎΠΉ ΠΈΠ· Π½Π°ΠΈΠΌΠ΅Π½Π΅Π΅ доступных подсистСм Π² ΠΌΠΈΡ€Π΅ Unix.

Π¨ΠΈΡ€ΠΎΠΊΠΎ распространСнными подсистСмами ΡΠ²Π»ΡΡŽΡ‚ΡΡ BSD sgtty, System termio, a Ρ‚Π°ΠΊΠΆΠ΅ POSIX termios. Π—Π° Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΠΎ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΡŽ Π²Ρ…ΠΎΠ΄Π½Ρ‹ΠΌΠΈ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ Π² Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ S-Lang ΠΎΡ‚Π²Π΅Ρ‡Π°ΡŽΡ‚ нСсколько Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½Ρ‹Ρ… ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΏΠΎΡΡ‚ΡƒΠΏΠ°ΡŽΡ‰ΠΈΡ… с ΠΊΠ»Π°Π²ΠΈΠ°Ρ‚ΡƒΡ€Ρ‹, Π±ΠΎΠ»Π΅Π΅ простой ΠΈ доступной.