#!/usr/bin/env slsh % This is a simple-minded implementation of a highlighting grep program % designed to test the pcre module. import ("pcre"); static define usage () { ()=fprintf(stderr, "Usage: %s [-inl] pattern [files...]\n", __argv[0]); exit (1); } static variable MATCH = 1; static variable LINENUM = 2; static variable FILENAME = 4; static variable Output_Format = 0; static define grep (file, p) { variable fp; if (file == NULL) fp = stdin; else fp = fopen (file, "r"); if (fp == NULL) { fprintf (stderr, "*** Unable to open %s\n", file); return; } variable linenum = 0; foreach (fp) using ("line") { variable str = (); linenum++; if (pcre_exec (p, str, 0)) { variable i0, i1, i; switch (Output_Format) { case FILENAME: () = fprintf (stdout, "%s\n", file); return; } { case LINENUM: () = fprintf (stdout, "%d\n", linenum); continue; } { case (MATCH|LINENUM): () = fprintf (stdout, "%d:", linenum); } { case (LINENUM|FILENAME): () = fprintf (stdout, "%s:%d\n", file, linenum); continue; } { case (LINENUM|FILENAME|MATCH): () = fprintf (stdout, "%s:%d:", file, linenum); } { case (FILENAME|MATCH): () = fprintf (stdout, "%s:", file); } do { i = pcre_nth_match (p, 0); i0 = i[0]; i1 = i[1]; if (i1 <= i0) break; if (i0 > 0) () = fprintf (stdout, "%s", str[[0:i0-1]]); () = fprintf (stdout, "\e[7m%s\e[m", str[[i0:i1-1]]); str = str[[i1:]]; } while (pcre_exec (p, str, 0)); () = fprintf (stdout, "%s", str); } } } static define main (argc, argv) { variable i; variable files, pattern; variable options; i = 1; files = NULL; pattern = NULL; options = 0; Output_Format = MATCH; while (i < argc) { variable arg = __argv[i]; i++; if (arg[0] == '-') { foreach (arg[[1:]]) { variable ch = (); switch (ch) { case 'i': options |= PCRE_CASELESS; } { case 'l': Output_Format &= ~MATCH; Output_Format |= FILENAME; } { case 'n': Output_Format |= LINENUM; } { () = fprintf (stderr, "Unsupported option: '%c'\n", ch); exit (1); } } continue; } pattern = arg; break; } if (pattern == NULL) usage (); variable p = pcre_compile (pattern, options); if (i == __argc) { if (isatty (stdin)) usage (); Output_Format &= ~FILENAME; grep (NULL, p); return; } files = argv[[i:]]; if (length(files) > 1) Output_Format |= FILENAME; foreach (files) { variable f = (); grep (f, p); } } public define slsh_main () { main (__argc, __argv); exit (0); }