/pliant/admin/asciifile.pli
 
 1  # Copyright  Hubert Tonneau  hubert.tonneau@pliant.cx 
 2  # 
 3  # This program is free software; you can redistribute it and/or 
 4  # modify it under the terms of the GNU General Public License version 2 
 5  # as published by the Free Software Foundation. 
 6  # 
 7  # This program is distributed in the hope that it will be useful, 
 8  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 9  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 10  # GNU General Public License for more details. 
 11  # 
 12  # You should have received a copy of the GNU General Public License 
 13  # version 2 along with this program; if not, write to the Free Software 
 14  # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
 15   
 16   
 17  abstract 
 18    [This modules provides basic functions for changing settings in ascii configuration files.] 
 19   
 20  doc 
 21    [The 'AsciiFile' data type is a superset of 'Array:Str', so the following methods are available:] 
 22    listing 
 23      var AsciiFile af 
 24      console af:size eol # the number of lines 
 25      console af:0 eol # the content of the first line 
 26      af += "one more line" # adds a line at the end. 
 27    para 
 28      [The following extra methods are also available:] 
 29      listing 
 30        af insert 3 "my line" 
 31      [Inserts a new line. The lines with indices ranging from 3 to the end are shifted.] 
 32      listing 
 33        af remove 3 
 34      [Removes the line with index 3. The lines with indices ranging from 4 to the end are shifted.] 
 35      listing 
 36        af get "CC" "=" 
 37      [Gets the value after the '=' sign in the line that looks like:] 
 38      listing 
 39         CC = anything 
 40      listing 
 41        af set "CC" "=" "CC = gcc272" 
 42      [or] 
 43      listing 
 44        af set "CC" "=" "CC = gcc272" 
 45      [Changes the line. ] 
 46    para 
 47      listing 
 48        af load "file:/tmp/test" 
 49        changing the content 
 50        af store 
 51      [Guess what it does.] 
 52   
 53   
 54  doc 
 55    [A complete sample could be (extracted from ] 
 56    link "/pliant/linux/kernel/build_kernel.pli" "/pliant/linux/kernel/build_kernel.pli" 
 57    [):] 
 58    listing 
 59      (var AsciiFile makefile) load "file:/usr/src/linux/Makefile" 
 60      makefile fuzzy_set "SMP" "=" "SMP = 1" 
 61      makefile set "HOSTCC" "=" "HOSTCC=gcc272" 
 62      makefile set "CC" "=" "CC=$(CROSS_COMPILE)gcc272 -D__KERNEL__ -I$(HPATH)" 
 63      makefile store 
 64  doc 
 65    [The main difference between 'set' and 'fuzzy_set' is that 'fuzzy_set' will accept a line that as something in front of the requested indentifier.] ; eol 
 66    para 
 67      [So,] 
 68      listing 
 69        makefile set "SMP" "=" "SMP = 1" 
 70      [would change line] 
 71      listing 
 72        SMP = 0 
 73      [to] 
 74      listing 
 75        SMP = 1 
 76      [but would not change] 
 77      listing 
 78        # SMP = 1 
 79      [On the other hand,] 
 80      listing 
 81        makefile fuzzy_set "SMP" "=" "SMP = 1" 
 82      [would change both.] 
 83     
 84  doc 
 85    [In the following example:] 
 86    listing 
 87      (var AsciiFile f) load "target:/etc/login.defs" 
 88      f set "PASS_MAX_LEN" "" "PASS_MAX_LEN 256" 
 89      f store 
 90    [the second argument is [dq][dq], so the line:] 
 91    listing 
 92      PASS_MAX_LEN 8 
 93    [will be changed to] 
 94    listing 
 95      PASS_MAX_LEN 256 
 96   
 97  doc 
 98    [Now the fairly trivial listing:] 
 99   
 100   
 101  module "/pliant/language/unsafe.pli" 
 102  module "/pliant/language/stream.pli" 
 103   
 104   
 105  type AsciiFile 
 106    field Str filename 
 107    field Array:Str lines 
 108   
 109   
 110  method af reset filename 
 111    arg_rw AsciiFile af ; arg Str filename 
 112    af filename := filename 
 113    af:lines size := 0 
 114   
 115  method af load filename 
 116    arg_rw AsciiFile af ; arg Str filename 
 117    af reset filename 
 118    (var Stream f) open filename in+safe 
 119    var Int := 0 
 120    while not f:atend 
 121      if i>=af:lines:size 
 122        af:lines size := max 2*af:lines:size 16 
 123      af:lines := readline 
 124      += 1 
 125    af:lines size := i 
 126   
 127  method af store -> status 
 128    arg_rw AsciiFile af ; arg Status status 
 129    (var Stream f) open af:filename out+mkdir+safe 
 130    for (var Int i) af:lines:size-1 
 131      writeline af:lines:i 
 132    status := close 
 133       
 134   
 135  method af size -> i 
 136    arg AsciiFile af ; arg Int i 
 137    := af:lines size 
 138     
 139  method af '' i -> l 
 140    arg AsciiFile af ; arg Int i ; arg_C Str l 
 141    check i>=and i<af:lines:size 
 142    :> af:lines i 
 143     
 144  function '+=' af l 
 145    arg_rw AsciiFile af ; arg Str l 
 146    af lines += l 
 147   
 148  method af insert i l 
 149    arg_rw AsciiFile af ; arg Int i ; arg Str l 
 150    check i>=and i<=af:size 
 151    af:lines size := af:size+1 
 152    for (var Int j) af:size-step -1 
 153      af j+:= af j 
 154    af := l 
 155     
 156  method af remove i 
 157    arg_rw AsciiFile af ; arg Int i 
 158    check i>=and i<af:size 
 159    for (var Int j) af:size-2 
 160      af := af j+1 
 161    af:lines size := af:size-1 
 162     
 163   
 164  method af get ident sign -> value 
 165    arg AsciiFile af ; arg Str ident sign value 
 166    for (var Int i) af:size-1 
 167      if (shunt sign<>"" (af:parse word:ident pattern:sign any:value) (af:parse word:ident any:value)) 
 168        return 
 169    value := "" 
 170   
 171  method af set ident sign line 
 172    arg_rw AsciiFile af ; arg Str ident sign line 
 173    for (var Int i) af:size-1 
 174      if (shunt sign<>"" (af:parse word:ident pattern:sign any) (af:parse word:ident any)) 
 175        af := line 
 176        return 
 177    af += line 
 178   
 179  method af fuzzy_set ident sign line 
 180    arg_rw AsciiFile af ; arg Str ident sign line 
 181    for (var Int i) af:size-1 
 182      if (shunt sign<>"" (af:parse any word:ident pattern:sign any) (af:parse any word:ident any)) 
 183        af := line 
 184        return 
 185    af += line 
 186   
 187  method af set_all ident sign line 
 188    arg_rw AsciiFile af ; arg Str ident sign line 
 189    for (var Int i) af:size-1 
 190      if (shunt sign<>"" (af:parse word:ident pattern:sign any) (af:parse word:ident any)) 
 191        af := line 
 192   
 193  method af replace pattern with 
 194    arg_rw AsciiFile af ; arg Str pattern with 
 195    for (var Int i) af:size-1 
 196      af := replace af:pattern with 
 197   
 198   
 199  export AsciiFile '. reset' '. load' '. store' 
 200  export '. size' '' '+=' '. insert' '. remove' 
 201  export '. get' '. set' '. fuzzy_set' '. set_all' '. replace' 
 202   
 203   
 204  function file_replace filename pattern with 
 205    arg Str filename pattern with 
 206    var AsciiFile af 
 207    af load filename 
 208    # console af:size " line(s) in " filename eol 
 209    af replace pattern with 
 210    af store 
 211   
 212  export file_replace