Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/build/build/make/tools/canoninja/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 3 kB image not shown  

Quelle  canoninja.go   Sprache: unbekannt

 
Spracherkennung für: .go vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

package canoninja

import (
 "bytes"
 "crypto/sha1"
 "encoding/hex"
 "fmt"
 "io"
)

var (
 rulePrefix  = []byte("rule ")
 buildPrefix = []byte("build ")
 phonyRule   = []byte("phony")
)

func Generate(path string, buffer []byte, sink io.Writer) error {
 // Break file into lines
 from := 0
 var lines [][]byte
 for from < len(buffer) {
  line := getLine(buffer[from:])
  lines = append(lines, line)
  from += len(line)
 }

 // FOr each rule, calculate and remember its digest
 ruleDigest := make(map[string]string)
 for i := 0; i < len(lines); {
  if bytes.HasPrefix(lines[i], rulePrefix) {
   // Find ruleName
   rn := ruleName(lines[i])
   if len(rn) == 0 {
    return fmt.Errorf("%s:%d: rule name is missing or on the next line", path, i+1)
   }
   sRuleName := string(rn)
   if _, ok := ruleDigest[sRuleName]; ok {
    return fmt.Errorf("%s:%d: the rule %s has been already defined", path, i+1, sRuleName)
   }
   // Calculate rule text digest as a digests of line digests.
   var digests []byte
   doDigest := func(b []byte) {
    h := sha1.New()
    h.Write(b)
    digests = h.Sum(digests)

   }
   // For the first line, digest everything after rule's name
   doDigest(lines[i][cap(lines[i])+len(rn)-cap(rn):])
   for i++; i < len(lines) && lines[i][0] == ' '; i++ {
    doDigest(lines[i])
   }
   h := sha1.New()
   h.Write(digests)
   ruleDigest[sRuleName] = "R" + hex.EncodeToString(h.Sum(nil))

  } else {
   i++
  }
 }

 // Rewrite rule names.
 for i, line := range lines {
  if bytes.HasPrefix(line, buildPrefix) {
   brn := getBuildRuleName(line)
   if bytes.Equal(brn, phonyRule) {
    sink.Write(line)
    continue
   }
   if len(brn) == 0 {
    return fmt.Errorf("%s:%d: build statement lacks rule name", path, i+1)
   }
   sink.Write(line[0 : cap(line)-cap(brn)])
   if digest, ok := ruleDigest[string(brn)]; ok {
    sink.Write([]byte(digest))
   } else {
    return fmt.Errorf("%s:%d: no rule for this build target", path, i+1)
   }
   sink.Write(line[cap(line)+len(brn)-cap(brn):])
  } else if bytes.HasPrefix(line, rulePrefix) {
   rn := ruleName(line)
   // Write everything before it
   sink.Write(line[0 : cap(line)-cap(rn)])
   sink.Write([]byte(ruleDigest[string(rn)]))
   sink.Write(line[cap(line)+len(rn)-cap(rn):])
  } else {
   //goland:noinspection GoUnhandledErrorResult
   sink.Write(line)
  }
 }
 return nil
}

func getLine(b []byte) []byte {
 if n := bytes.IndexByte(b, '\n'); n >= 0 {
  return b[:n+1]
 }
 return b
}

// Returns build statement's rule name
func getBuildRuleName(line []byte) []byte {
 n := bytes.IndexByte(line, ':')
 if n <= 0 {
  return nil
 }
 ruleName := line[n+1:]
 if ruleName[0] == ' ' {
  ruleName = bytes.TrimLeft(ruleName, " ")
 }
 if n := bytes.IndexAny(ruleName, " \t\r\n"); n >= 0 {
  ruleName = ruleName[0:n]
 }
 return ruleName
}

// Returns rule statement's rule name
func ruleName(lineAfterRule []byte) []byte {
 ruleName := lineAfterRule[len(rulePrefix):]
 if len(ruleName) == 0 {
  return ruleName
 }
 if ruleName[0] == ' ' {
  ruleName = bytes.TrimLeft(ruleName, " ")
 }
 if n := bytes.IndexAny(ruleName, " \t\r\n"); n >= 0 {
  ruleName = ruleName[0:n]
 }
 return ruleName
}

[Dauer der Verarbeitung: 0.18 Sekunden, vorverarbeitet 2026-06-28]