9fans.net/go@v0.0.7/cmd/acme/internal/runes/runes.go (about)

     1  // #include <u.h>
     2  // #include <libc.h>
     3  // #include <draw.h>
     4  // #include <thread.h>
     5  // #include <cursor.h>
     6  // #include <mouse.h>
     7  // #include <keyboard.h>
     8  // #include <frame.h>
     9  // #include <fcall.h>
    10  // #include <regexp.h>
    11  // #include <9pclient.h>
    12  // #include <plumb.h>
    13  // #include <libsec.h>
    14  // #include "dat.h"
    15  // #include "fns.h"
    16  
    17  package runes
    18  
    19  import (
    20  	"path"
    21  	"strings"
    22  	"unicode/utf8"
    23  )
    24  
    25  func Index(r, s []rune) int {
    26  	if len(s) == 0 {
    27  		return 0
    28  	}
    29  	c := s[0]
    30  	for i, ri := range r {
    31  		if len(r)-i < len(s) {
    32  			break
    33  		}
    34  		if ri == c && Equal(r[i:i+len(s)], s) {
    35  			return i
    36  		}
    37  	}
    38  	return -1
    39  }
    40  
    41  func IndexRune(rs []rune, c rune) int {
    42  	for i, r := range rs {
    43  		if r == c {
    44  			return i
    45  		}
    46  	}
    47  	return -1
    48  }
    49  
    50  func Compare(a, b []rune) int {
    51  	for i := 0; i < len(a) && i < len(b); i++ {
    52  		if a[i] != b[i] {
    53  			if a[i] < b[i] {
    54  				return -1
    55  			}
    56  			return +1
    57  		}
    58  	}
    59  	if len(a) < len(b) {
    60  		return -1
    61  	}
    62  	if len(a) > len(b) {
    63  		return +1
    64  	}
    65  	return 0
    66  }
    67  
    68  func Equal(s1, s2 []rune) bool {
    69  	if len(s1) != len(s2) {
    70  		return false
    71  	}
    72  	for i := 0; i < len(s1); i++ {
    73  		if s1[i] != s2[i] {
    74  			return false
    75  		}
    76  	}
    77  	return true
    78  }
    79  
    80  func Clone(r []rune) []rune {
    81  	s := make([]rune, len(r))
    82  	copy(s, r)
    83  	return s
    84  }
    85  
    86  func IsAlphaNum(c rune) bool {
    87  	/*
    88  	 * Hard to get absolutely right.  Use what we know about ASCII
    89  	 * and assume anything above the Latin control characters is
    90  	 * potentially an alphanumeric.
    91  	 */
    92  	if c <= ' ' {
    93  		return false
    94  	}
    95  	if 0x7F <= c && c <= 0xA0 {
    96  		return false
    97  	}
    98  	if strings.ContainsRune("!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~", c) {
    99  		return false
   100  	}
   101  	return true
   102  }
   103  
   104  var isfilec_Lx = []rune(".-+/:@")
   105  
   106  func IsFilename(r rune) bool {
   107  	if IsAlphaNum(r) {
   108  		return true
   109  	}
   110  	if IndexRune(isfilec_Lx, r) >= 0 {
   111  		return true
   112  	}
   113  	return false
   114  }
   115  
   116  func SkipBlank(r []rune) []rune {
   117  	for len(r) > 0 && (r[0] == ' ' || r[0] == '\t' || r[0] == '\n') {
   118  		r = r[1:]
   119  	}
   120  	return r
   121  }
   122  
   123  func SkipNonBlank(r []rune) []rune {
   124  	for len(r) > 0 && r[0] != ' ' && r[0] != '\t' && r[0] != '\n' {
   125  		r = r[1:]
   126  	}
   127  	return r
   128  }
   129  
   130  // Convert converts bytes in b to runes in r,
   131  // returning the number of bytes processed from b,
   132  // the number of runes written to r,
   133  // and whether any null bytes were elided.
   134  // If eof is true, then any partial runes at the end of b
   135  // should be processed, and nb == len(b) at return.
   136  // Otherwise, partial runes are left behind and
   137  // nb may be up to utf8.UTFMax-1 bytes short of len(b).
   138  func Convert(b []byte, r []rune, eof bool) (nb, nr int, nulls bool) {
   139  	b0 := b
   140  	for len(b) > 0 && (eof || len(b) >= utf8.UTFMax || utf8.FullRune(b)) {
   141  		rr, w := utf8.DecodeRune(b)
   142  		if rr == 0 {
   143  			nulls = true
   144  		} else {
   145  			r[nr] = rr
   146  			nr++
   147  		}
   148  		b = b[w:]
   149  	}
   150  	nb = len(b0) - len(b)
   151  	return nb, nr, nulls
   152  }
   153  
   154  func CleanPath(r []rune) []rune {
   155  	return []rune(path.Clean(string(r)))
   156  }
   157  
   158  type Range struct {
   159  	Pos int
   160  	End int
   161  }
   162  
   163  func Rng(q0 int, q1 int) Range {
   164  	var r Range
   165  	r.Pos = q0
   166  	r.End = q1
   167  	return r
   168  }
   169  
   170  const Infinity = 0x7FFFFFFF
   171  
   172  const RuneSize = 4
   173  
   174  func IsAddr(r rune) bool {
   175  	if r != 0 && strings.ContainsRune("0123456789+-/$.#,;?", r) {
   176  		return true
   177  	}
   178  	return false
   179  }
   180  
   181  /*
   182   * quite hard: could be almost anything but white space, but we are a little conservative,
   183   * aiming for regular expressions of alphanumerics and no white space
   184   */
   185  func IsRegx(r rune) bool {
   186  	if r == 0 {
   187  		return false
   188  	}
   189  	if IsAlphaNum(r) {
   190  		return true
   191  	}
   192  	if strings.ContainsRune("^+-.*?#,;[]()$", r) {
   193  		return true
   194  	}
   195  	return false
   196  }