]> git.sur5r.net Git - cc65/blob - libsrc/common/putenv.s
Removed (pretty inconsistently used) tab chars from source code base.
[cc65] / libsrc / common / putenv.s
1 ;
2 ; Ullrich von Bassewitz, 2005-04-21
3 ;
4 ; int putenv (char* s);
5 ;
6 ; Note: The function will place s into the environment, *not* a copy!
7 ;
8
9         .export _putenv
10         .import _malloc, _free
11         .import searchenv, copyenvptr
12         .import __environ, __envcount, __envsize
13         .import return0
14         .import ptr1:zp, ptr2:zp, ptr3:zp, tmp1:zp
15
16         .include "errno.inc"
17
18 .code
19
20 ;----------------------------------------------------------------------------
21 ; putenv()
22
23 .proc   _putenv
24
25         sta     ptr1
26         sta     name
27         stx     ptr1+1                  ; Save name
28         stx     name+1
29
30 ; Loop over the name to find the '='. If there is no '=', set errno to EINVAL
31 ; and return an error.
32
33         ldy     #$FF
34 @L0:    iny
35         lda     (ptr1),y
36         bne     @L1
37         lda     #EINVAL
38         jmp     error                   ; End of string without '=' found
39 @L1:    cmp     #'='
40         bne     @L0
41
42 ; Remember the offset of the equal sign and replace it by a zero.
43
44         sty     tmp1
45         lda     #$00
46         sta     (ptr1),y
47
48 ; Search for the string in the environment. searchenv will set the N flag if
49 ; the string is not found, otherwise X contains the index of the entry, ptr2
50 ; contains the entry and Y the offset of the '=' in the string. ptr3 will
51 ; point to the environment.
52
53         jsr     searchenv
54
55 ; Before doing anything else, restore the old environment string.
56
57         ldy     tmp1
58         lda     #'='
59         sta     (ptr1),y
60
61 ; Check the result of searchenv
62
63         txa                             ; Did we find the entry?
64         bpl     addentry                ; Jump if yes
65
66 ; We didn't find the entry, so we have to add a new one. Before doing so, we
67 ; must check if the size of the _environ array must be increased.
68 ; Note: There must be one additional slot for the final NULL entry.
69
70         ldx     __envcount
71         inx
72         cpx     __envsize
73         bcc     addnewentry             ; Jump if space enough
74
75 ; We need to increase the size of the environ array. Calculate the new size.
76 ; We will not support a size larger than 64 entries, double the size with
77 ; each overflow, and the starting size is 8 entries.
78
79         lda     __envsize
80         bne     @L2
81         lda     #4                      ; Start with 4*2 entries
82 @L2:    asl     a                       ; Double current size
83         bmi     nomem                   ; Bail out if > 64
84         sta     newsize                 ; Remember the new size
85
86 ; Call malloc() and store the result in ptr2
87
88         asl     a                       ; Make words
89         ldx     #$00
90         jsr     _malloc
91         sta     ptr2
92         stx     ptr2+1
93
94 ; Check the result of malloc
95
96         ora     ptr2+1
97         beq     nomem
98
99 ; Copy the old environment pointer to ptr3, and the new one to __environ.
100
101         ldx     #1
102 @L3:    lda     __environ,x
103         sta     ptr3,x
104         lda     ptr2,x
105         sta     __environ,x
106         dex
107         bpl     @L3
108
109 ; Use the new size.
110
111         lda     newsize
112         sta     __envsize
113
114 ; Copy the old environment data into the new space.
115
116         lda     __envcount
117         asl     a
118         tay
119         jmp     @L5
120 @L4:    lda     (ptr3),y
121         sta     (ptr2),y
122 @L5:    dey
123         bpl     @L4
124
125 ; Free the old environment space
126
127         lda     ptr3
128         ldx     ptr3+1
129         jsr     _free
130
131 ; Since free() has destroyed ptr2, we need another copy ...
132
133         jsr     copyenvptr              ; Copy __environ to ptr2
134
135 ; Bump the environment count and remember it in X. Add the final NULL entry.
136
137 addnewentry:
138         inc     __envcount
139         ldx     __envcount
140         txa
141         asl     a
142         tay
143         lda     #$00
144         sta     (ptr2),y
145         iny
146         sta     (ptr2),y
147
148 ; The index of the new entry is the old environment count.
149
150         dex
151         txa
152
153 ; Add the new entry to the slot with index in X. The pointer to the environment
154 ; is already in ptr2, either by a call to searchenv, or by above code.
155
156 addentry:
157         asl     a
158         tay
159         lda     name
160         sta     (ptr2),y
161         iny
162         lda     name+1
163         sta     (ptr2),y
164
165 ; Done
166
167         jmp     return0
168
169 ; Error entries
170
171 nomem:  lda     #ENOMEM
172 error:  jsr     __seterrno
173         lda     #$FF                    ; Return -1
174         tax
175         rts
176
177 .endproc
178
179
180 ;----------------------------------------------------------------------------
181 ; data
182
183 .bss
184
185 name:           .addr   0               ; Pointer to name
186 newsize:        .byte   0               ; New environment size
187
188