#!/usr/bin/env slsh % This is a simple-minded implementation of a highlighting grep program % designed to test the onig module. require ("onig"); require ("cmdopt"); private define usage () { ()=fprintf(stderr, "Usage: %s [-inl] [--syntax syntax] pattern [files...]\n", __argv[0]); exit (1); } private variable MATCH = 1; private variable LINENUM = 2; private variable FILENAME = 4; private variable Output_Format = 0; private 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 (onig_search (p, str)) { 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 = onig_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 (onig_search (p, str)); () = fprintf (stdout, "%s", str); } } } define slsh_main () { variable options; options = 0; Output_Format = MATCH; variable syntax = "perl"; variable opts = cmdopt_new (); opts.add ("i", &options; bor=ONIG_OPTION_IGNORECASE); opts.add ("n", &Output_Format; bor=LINENUM); opts.add ("l", &Output_Format; bor=FILENAME, band=~MATCH); opts.add ("h|help", &usage); opts.add ("s|syntax", &syntax); variable i = opts.process (__argv, 1); if (i + 1 > __argc) usage (); variable pattern = __argv[i]; i++; variable reg = onig_new (pattern, options, "utf8", syntax); if (i == __argc) { if (isatty (stdin)) usage (); Output_Format &= ~FILENAME; grep (NULL, reg); return; } variable files = __argv[[i:]]; if (length(files) > 1) Output_Format |= FILENAME; foreach (files) { variable f = (); grep (f, reg); } }