OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [net/] [athttpd/] [current/] [src/] [jim-aio.c] - Blame information for rev 867

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
/* Jim - ANSI I/O extension
2
 * Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>
3
 *
4
 * $Id: jim-aio.c,v 1.10 2006/11/06 16:54:48 antirez Exp $
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * A copy of the license is also included in the source distribution
13
 * of Jim, as a TXT file name called LICENSE.
14
 *
15
 * Unless required by applicable law or agreed to in writing, software
16
 * distributed under the License is distributed on an "AS IS" BASIS,
17
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
 * See the License for the specific language governing permissions and
19
 * limitations under the License.
20
 */
21
 
22
#include <stdio.h>
23
#include <string.h>
24
#include <errno.h>
25
 
26
#include <pkgconf/athttpd.h>
27
#ifndef JIM_STATICEXT
28
#define JIM_EXTENSION
29
#endif
30
#include <cyg/athttpd/jim.h>
31
 
32
#define AIO_CMD_LEN 128
33
#define AIO_BUF_LEN 1024
34
 
35
typedef struct AioFile {
36
    FILE *fp;
37
    int keepOpen; /* If set, the file is not fclosed on cleanup (stdin, ...) */
38
} AioFile;
39
 
40
static void JimAioSetError(Jim_Interp *interp)
41
{
42
    Jim_SetResultString(interp, strerror(errno), -1);
43
}
44
 
45
static void JimAioDelProc(Jim_Interp *interp, void *privData)
46
{
47
    AioFile *af = privData;
48
    JIM_NOTUSED(interp);
49
 
50
    if (!af->keepOpen)
51
        fclose(af->fp);
52
    Jim_Free(af);
53
}
54
 
55
/* Calls to [aio.file] create commands that are implemented by this
56
 * C command. */
57
static int JimAioHandlerCommand(Jim_Interp *interp, int argc,
58
        Jim_Obj *const *argv)
59
{
60
    AioFile *af = Jim_CmdPrivData(interp);
61
    int option;
62
    const char *options[] = {
63
        "close", "seek", "tell", "gets", "read", "puts", "flush", "eof", NULL
64
    };
65
    enum {OPT_CLOSE, OPT_SEEK, OPT_TELL, OPT_GETS, OPT_READ, OPT_PUTS,
66
          OPT_FLUSH, OPT_EOF};
67
 
68
    if (argc < 2) {
69
        Jim_WrongNumArgs(interp, 1, argv, "method ?args ...?");
70
        return JIM_ERR;
71
    }
72
    if (Jim_GetEnum(interp, argv[1], options, &option, "AIO method",
73
                JIM_ERRMSG) != JIM_OK)
74
        return JIM_ERR;
75
    /* CLOSE */
76
    if (option == OPT_CLOSE) {
77
        if (argc != 2) {
78
            Jim_WrongNumArgs(interp, 2, argv, "");
79
            return JIM_ERR;
80
        }
81
        Jim_DeleteCommand(interp, Jim_GetString(argv[0], NULL));
82
        return JIM_OK;
83
    } else if (option == OPT_SEEK) {
84
    /* SEEK */
85
        int orig = SEEK_SET;
86
        long offset;
87
 
88
        if (argc != 3 && argc != 4) {
89
            Jim_WrongNumArgs(interp, 2, argv, "offset ?origin?");
90
            return JIM_ERR;
91
        }
92
        if (argc == 4) {
93
            if (Jim_CompareStringImmediate(interp, argv[3], "start"))
94
                orig = SEEK_SET;
95
            else if (Jim_CompareStringImmediate(interp, argv[3], "current"))
96
                orig = SEEK_CUR;
97
            else if (Jim_CompareStringImmediate(interp, argv[3], "end"))
98
                orig = SEEK_END;
99
            else {
100
                Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
101
                Jim_AppendStrings(interp, Jim_GetResult(interp),
102
                        "bad origin \"", Jim_GetString(argv[3], NULL),
103
                        "\" must be: start, current, or end", NULL);
104
                return JIM_ERR;
105
            }
106
        }
107
        if (Jim_GetLong(interp, argv[2], &offset) != JIM_OK)
108
            return JIM_ERR;
109
        if (fseek(af->fp, offset, orig) == -1) {
110
            JimAioSetError(interp);
111
            return JIM_ERR;
112
        }
113
        return JIM_OK;
114
    } else if (option == OPT_TELL) {
115
    /* TELL */
116
        long position;
117
 
118
        if (argc != 2) {
119
            Jim_WrongNumArgs(interp, 2, argv, "");
120
            return JIM_ERR;
121
        }
122
        position = ftell(af->fp);
123
        Jim_SetResult(interp, Jim_NewIntObj(interp, position));
124
        return JIM_OK;
125
    } else if (option == OPT_GETS) {
126
    /* GETS */
127
        char buf[AIO_BUF_LEN];
128
        Jim_Obj *objPtr;
129
 
130
        if (argc != 2 && argc != 3) {
131
            Jim_WrongNumArgs(interp, 2, argv, "?varName?");
132
            return JIM_ERR;
133
        }
134
        objPtr = Jim_NewStringObj(interp, NULL, 0);
135
        while (1) {
136
            int more = 0;
137
            buf[AIO_BUF_LEN-1] = '_';
138
            if (fgets(buf, AIO_BUF_LEN, af->fp) == NULL)
139
                break;
140
            if (buf[AIO_BUF_LEN-1] == '\0' && buf[AIO_BUF_LEN-2] == '\n')
141
                more = 1;
142
            if (more) {
143
                Jim_AppendString(interp, objPtr, buf, AIO_BUF_LEN-1);
144
            } else {
145
                /* strip "\n" */
146
                Jim_AppendString(interp, objPtr, buf, strlen(buf)-1);
147
            }
148
            if (!more)
149
                break;
150
        }
151
        if (ferror(af->fp)) {
152
            /* I/O error */
153
            Jim_IncrRefCount(objPtr);
154
            Jim_DecrRefCount(interp, objPtr);
155
            JimAioSetError(interp);
156
            return JIM_ERR;
157
        }
158
        /* On EOF returns -1 if varName was specified, or the empty string. */
159
        if (feof(af->fp) && Jim_Length(objPtr) == 0) {
160
            Jim_IncrRefCount(objPtr);
161
            Jim_DecrRefCount(interp, objPtr);
162
            if (argc == 3)
163
                Jim_SetResult(interp, Jim_NewIntObj(interp, -1));
164
            return JIM_OK;
165
        }
166
        if (argc == 3) {
167
            int totLen;
168
 
169
            Jim_GetString(objPtr, &totLen);
170
            if (Jim_SetVariable(interp, argv[2], objPtr) != JIM_OK) {
171
                Jim_IncrRefCount(objPtr);
172
                Jim_DecrRefCount(interp, objPtr);
173
                return JIM_ERR;
174
            }
175
            Jim_SetResult(interp, Jim_NewIntObj(interp, totLen));
176
        } else {
177
            Jim_SetResult(interp, objPtr);
178
        }
179
        return JIM_OK;
180
    } else if (option == OPT_READ) {
181
    /* READ */
182
        char buf[AIO_BUF_LEN];
183
        Jim_Obj *objPtr;
184
        int nonewline = 0;
185
        int neededLen = -1; /* -1 is "read as much as possible" */
186
 
187
        if (argc != 2 && argc != 3) {
188
            Jim_WrongNumArgs(interp, 2, argv, "?-nonewline? ?len?");
189
            return JIM_ERR;
190
        }
191
        if (argc == 3 &&
192
            Jim_CompareStringImmediate(interp, argv[2], "-nonewline"))
193
        {
194
            nonewline = 1;
195
            argv++;
196
            argc--;
197
        }
198
        if (argc == 3) {
199
            jim_wide wideValue;
200
            if (Jim_GetWide(interp, argv[2], &wideValue) != JIM_OK)
201
                return JIM_ERR;
202
            if (wideValue < 0) {
203
                Jim_SetResultString(interp, "invalid parameter: negative len",
204
                        -1);
205
                return JIM_ERR;
206
            }
207
            neededLen = (int) wideValue;
208
        }
209
        objPtr = Jim_NewStringObj(interp, NULL, 0);
210
        while (neededLen != 0) {
211
            int retval;
212
            int readlen;
213
 
214
            if (neededLen == -1) {
215
                readlen = AIO_BUF_LEN;
216
            } else {
217
                readlen = (neededLen > AIO_BUF_LEN ? AIO_BUF_LEN : neededLen);
218
            }
219
            retval = fread(buf, 1, readlen, af->fp);
220
            if (retval > 0) {
221
                Jim_AppendString(interp, objPtr, buf, retval);
222
                if (neededLen != -1) {
223
                    neededLen -= retval;
224
                }
225
            }
226
            if (retval != readlen) break;
227
        }
228
        /* Check for error conditions */
229
        if (ferror(af->fp)) {
230
            /* I/O error */
231
            Jim_FreeNewObj(interp, objPtr);
232
            JimAioSetError(interp);
233
            return JIM_ERR;
234
        }
235
        if (nonewline) {
236
            int len;
237
            const char *s = Jim_GetString(objPtr, &len);
238
 
239
            if (len > 0 && s[len-1] == '\n') {
240
                objPtr->length--;
241
                objPtr->bytes[objPtr->length] = '\0';
242
            }
243
        }
244
        Jim_SetResult(interp, objPtr);
245
        return JIM_OK;
246
    } else if (option == OPT_PUTS) {
247
    /* PUTS */
248
        int wlen;
249
        const char *wdata;
250
 
251
        if (argc != 3 && (argc != 4 || !Jim_CompareStringImmediate(
252
                        interp, argv[2], "-nonewline"))) {
253
            Jim_WrongNumArgs(interp, 2, argv, "?-nonewline? string");
254
            return JIM_ERR;
255
        }
256
        wdata = Jim_GetString(argv[2+(argc==4)], &wlen);
257
        if (fwrite(wdata, 1, wlen, af->fp) != (unsigned)wlen ||
258
            (argc == 3 && fwrite("\n", 1, 1, af->fp) != 1)) {
259
            JimAioSetError(interp);
260
            return JIM_ERR;
261
        }
262
        return JIM_OK;
263
    } else if (option  == OPT_FLUSH) {
264
    /* FLUSH */
265
        if (argc != 2) {
266
            Jim_WrongNumArgs(interp, 2, argv, "");
267
            return JIM_ERR;
268
        }
269
        if (fflush(af->fp) == EOF) {
270
            JimAioSetError(interp);
271
            return JIM_ERR;
272
        }
273
        return JIM_OK;
274
    } else if (option  == OPT_EOF) {
275
    /* EOF */
276
        if (argc != 2) {
277
            Jim_WrongNumArgs(interp, 2, argv, "");
278
            return JIM_ERR;
279
        }
280
        Jim_SetResult(interp, Jim_NewIntObj(interp, feof(af->fp)));
281
        return JIM_OK;
282
    }
283
    return JIM_OK;
284
}
285
 
286
static int JimAioOpenCommand(Jim_Interp *interp, int argc,
287
        Jim_Obj *const *argv)
288
{
289
    FILE *fp;
290
    AioFile *af;
291
    char buf[AIO_CMD_LEN];
292
    const char *mode = "r";
293
    Jim_Obj *objPtr;
294
    long fileId;
295
    const char *options[] = {"input", "output", "error"};
296
    enum {OPT_INPUT, OPT_OUTPUT, OPT_ERROR};
297
    int keepOpen = 0, modeLen;
298
 
299
    if (argc != 2 && argc != 3) {
300
        Jim_WrongNumArgs(interp, 1, argv, "filename ?mode?");
301
        return JIM_ERR;
302
    }
303
    if (argc == 3)
304
        mode = Jim_GetString(argv[2], &modeLen);
305
    if (argc == 3 && Jim_CompareStringImmediate(interp, argv[1], "standard") &&
306
            modeLen >= 3) {
307
            int option;
308
        if (Jim_GetEnum(interp, argv[2], options, &option, "standard channel",
309
                    JIM_ERRMSG) != JIM_OK)
310
            return JIM_ERR;
311
        keepOpen = 1;
312
        switch (option) {
313
        case OPT_INPUT: fp = stdin; break;
314
        case OPT_OUTPUT: fp = stdout; break;
315
        case OPT_ERROR: fp = stderr; break;
316
        default: fp = NULL; Jim_Panic(interp,"default reached in JimAioOpenCommand()");
317
                 break;
318
        }
319
    } else {
320
        fp = fopen(Jim_GetString(argv[1], NULL), mode);
321
        if (fp == NULL) {
322
            JimAioSetError(interp);
323
            return JIM_ERR;
324
        }
325
    }
326
    /* Get the next file id */
327
    if (Jim_EvalGlobal(interp,
328
                "if {[catch {incr aio.fileId}]} {set aio.fileId 0}") != JIM_OK)
329
        return JIM_ERR;
330
    objPtr = Jim_GetGlobalVariableStr(interp, "aio.fileId", JIM_ERRMSG);
331
    if (objPtr == NULL) return JIM_ERR;
332
    if (Jim_GetLong(interp, objPtr, &fileId) != JIM_OK) return JIM_ERR;
333
 
334
    /* Create the file command */
335
    af = Jim_Alloc(sizeof(*af));
336
    af->fp = fp;
337
    af->keepOpen = keepOpen;
338
    sprintf(buf, "aio.handle%ld", fileId);
339
    Jim_CreateCommand(interp, buf, JimAioHandlerCommand, af, JimAioDelProc);
340
    Jim_SetResultString(interp, buf, -1);
341
    return JIM_OK;
342
}
343
 
344
#ifndef JIM_STATICEXT
345
int Jim_OnLoad(Jim_Interp *interp)
346
#else
347
int Jim_AioInit(Jim_Interp *interp)
348
#endif
349
{
350
    #ifndef JIM_STATICEXT
351
    Jim_InitExtension(interp);
352
    #endif
353
    if (Jim_PackageProvide(interp, "aio", "1.0", JIM_ERRMSG) != JIM_OK)
354
        return JIM_ERR;
355
    Jim_CreateCommand(interp, "aio.open", JimAioOpenCommand, NULL, NULL);
356
    return JIM_OK;
357
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.