XINU
lexan.c
Go to the documentation of this file.
1 /* lexan.c - lexan */
2 
3 #include <xinu.h>
4 
5 /*------------------------------------------------------------------------
6  * lexan - Ad hoc lexical analyzer to divide command line into tokens
7  *------------------------------------------------------------------------
8  */
9 
11  char *line, /* Input line terminated with */
12  /* NEWLINE or NULLCH */
13  int32 len, /* Length of the input line, */
14  /* including NEWLINE */
15  char *tokbuf, /* Buffer into which tokens are */
16  /* stored with a null */
17  /* following each token */
18  int32 *tlen, /* Place to store number of */
19  /* chars in tokbuf */
20  int32 tok[], /* Array of pointers to the */
21  /* start of each token */
22  int32 toktyp[] /* Array that gives the type */
23  /* of each token */
24  )
25 {
26  char quote; /* Character for quoted string */
27  uint32 ntok; /* Number of tokens found */
28  char *p; /* Pointer that walks along the */
29  /* input line */
30  int32 tbindex; /* Index into tokbuf */
31  char ch; /* Next char from input line */
32 
33  /* Start at the beginning of the line with no tokens */
34 
35  ntok = 0;
36  p = line;
37  tbindex = 0;
38 
39  /* While not yet at end of line, get next token */
40 
41  while ( (*p != NULLCH) && (*p != SH_NEWLINE) ) {
42 
43  /* If too many tokens, return error */
44 
45  if (ntok >= SHELL_MAXTOK) {
46  return SYSERR;
47  }
48 
49  /* Skip whitespace before token */
50 
51  while ( (*p == SH_BLANK) || (*p == SH_TAB) ) {
52  p++;
53  }
54 
55  /* Stop parsing at end of line (or end of string) */
56 
57  ch = *p;
58  if ( (ch==SH_NEWLINE) || (ch==NULLCH) ) {
59  *tlen = tbindex;
60  return ntok;
61  }
62 
63  /* Set next entry in tok array to be an index to the */
64  /* current location in the token buffer */
65 
66  tok[ntok] = tbindex; /* the start of the token */
67 
68  /* Set the token type */
69 
70  switch (ch) {
71 
72  case SH_AMPER: toktyp[ntok] = SH_TOK_AMPER;
73  tokbuf[tbindex++] = ch;
74  tokbuf[tbindex++] = NULLCH;
75  ntok++;
76  p++;
77  continue;
78 
79  case SH_LESS: toktyp[ntok] = SH_TOK_LESS;
80  tokbuf[tbindex++] = ch;
81  tokbuf[tbindex++] = NULLCH;
82  ntok++;
83  p++;
84  continue;
85 
86  case SH_GREATER: toktyp[ntok] = SH_TOK_GREATER;
87  tokbuf[tbindex++] = ch;
88  tokbuf[tbindex++] = NULLCH;
89  ntok++;
90  p++;
91  continue;
92 
93  default: toktyp[ntok] = SH_TOK_OTHER;
94  };
95 
96  /* Handle quoted string (single or double quote) */
97 
98  if ( (ch==SH_SQUOTE) || (ch==SH_DQUOTE) ) {
99  quote = ch; /* remember opening quote */
100 
101  /* Copy quoted string to arg area */
102 
103  p++; /* Move past starting quote */
104 
105  while ( ((ch=*p++) != quote) && (ch != SH_NEWLINE)
106  && (ch != NULLCH) ) {
107  tokbuf[tbindex++] = ch;
108  }
109  if (ch != quote) { /* string missing end quote */
110  return SYSERR;
111  }
112 
113  /* Finished string - count token and go on */
114 
115  tokbuf[tbindex++] = NULLCH; /* terminate token */
116  ntok++; /* count string as one token */
117  continue; /* go to next token */
118  }
119 
120  /* Handle a token other than a quoted string */
121 
122  tokbuf[tbindex++] = ch; /* put first character in buffer*/
123  p++;
124 
125  while ( ((ch = *p) != SH_NEWLINE) && (ch != NULLCH)
126  && (ch != SH_LESS) && (ch != SH_GREATER)
127  && (ch != SH_BLANK) && (ch != SH_TAB)
128  && (ch != SH_AMPER) && (ch != SH_SQUOTE)
129  && (ch != SH_DQUOTE) ) {
130  tokbuf[tbindex++] = ch;
131  p++;
132  }
133 
134  /* Report error if other token is appended */
135 
136  if ( (ch == SH_SQUOTE) || (ch == SH_DQUOTE)
137  || (ch == SH_LESS) || (ch == SH_GREATER) ) {
138  return SYSERR;
139  }
140 
141  tokbuf[tbindex++] = NULLCH; /* terminate the token */
142 
143  ntok++; /* count valid token */
144 
145  }
146  *tlen = tbindex;
147  return ntok;
148 }
#define SH_TOK_GREATER
大なり&#39;>&#39;トークン
Definition: shell.h:79
#define SH_AMPER
アンパサンド文字&#39;&&#39;(字句解析時に用いる)
Definition: shell.h:60
全てのシステムヘッダファイルをインクルードする。
#define SH_TAB
TAB文字(字句解析時に用いる)
Definition: shell.h:64
#define SYSERR
処理が失敗した場合
Definition: kernel.h:79
#define SH_BLANK
ブランク(空白)文字(字句解析時に用いる)
Definition: shell.h:62
#define SH_TOK_OTHER
その他(&#39;&&#39;、&#39;<&#39;、&#39;>以外&#39;)のトークン(例:英数字文字列)
Definition: shell.h:81
#define SH_SQUOTE
シングルクォート文字&#39;&#39;&#39;(字句解析時に用いる)
Definition: shell.h:66
#define SH_NEWLINE
LF改行コード&#39; &#39;(字句解析時に用いる)
Definition: shell.h:56
int32 lexan(char *line, int32 len, char *tokbuf, int32 *tlen, int32 tok[], int32 toktyp[])
Definition: lexan.c:10
#define SHELL_MAXTOK
一行あたりの最大トークン数
Definition: shell.h:9
#define SH_DQUOTE
ダブルクォート文字&#39;"&#39;(字句解析時に用いる)
Definition: shell.h:68
int int32
符号あり32ビット整数(int)
Definition: kernel.h:11
#define SH_GREATER
大なり記号&#39;>&#39;
Definition: shell.h:72
#define SH_TOK_AMPER
アンパサンド&#39;&&#39;トークン
Definition: shell.h:75
unsigned int uint32
符号なし32ビット整数(unsigned int)
Definition: kernel.h:15
#define SH_LESS
小なり記号&#39;<&#39;
Definition: shell.h:70
#define NULLCH
NULL文字(NULL終端)
Definition: kernel.h:70
#define SH_TOK_LESS
小なり&#39;<&#39;トークン
Definition: shell.h:77