1. string literal definition in c language
1> "hello world" // ok
2> L"hello world" // ok (wide character for representing chinese, japanese)
3> "i " "love " "you" // ok, apply string concetation
4> "i " "love "
"you" // ok, apply string concetation
5> "" // ok, empty string
6> "hello
world" // error
7> "hello /
tworld" // error of c definition, but compile succeessfully in lcc & gcc [1]
2. call relationship
expression // expr.c, see primary(void)
|---> STRING_LITERAL_DFA // gettok()
|---> scanner // scon()
|---> get escape sequence // backslash()
|---> copy string literal into buffer // cput(), or wcput()
|---> storage buffer for string literal // char cbuf[BUFSIZE+1], or wchar wcbuf[BUFSIZE+1]
3. comment on source code
// comments on scanner of string literal, in lex.c
813 static void *scon(int q, void *put(int c, void *cl), void *cl) {
814 int n = 0, nbad = 0; // n counts how many characters in string literal
815 // q is the enclosing character, for example '/"'(double quotes)
816 do {
817 cp++;
818 while (*cp != q) {
819 int c;
820 if (map[*cp]&NEWLINE) {
821 if (cp < limit) // like 6> invalid occurence of literal string definition, goto error
822 break;
823 cp++;
824 nextline();
825 if (cp == limit) // reach EOF, but without matching the enclosing character, goto error
826 break;
827 continue;
828 }
829 c = *cp++;
830 if (c == '//') {
831 if (map[*cp]&NEWLINE) {
832 if (cp < limit) // like 7> invalide occurence of literal string definition, goto error
833 break;
834 cp++;
835 nextline();
836 }
837 if (limit - cp < MAXTOKEN)
838 fillbuf();
839 c = backslash(q); // deal with escape sequence
840 } else if (c < 0 || c > 255 || map[c] == 0) // ? not sure of the use
841 nbad++;
842 if (n++ < BUFSIZE)
843 cl = put(c, cl); // stores string literals in cbuf[BUFSIZE+1] or wcbuf[BUFSIZE+1]
844 }
845 if (*cp == q)
846 cp++;
847 else
848 error("missing %c/n", q);
849 } while (q == '"' && getchr() == '"'); // there is an '/"' after the literal string, so apply string concetation
850 cl = put(0, cl);
851 if (n >= BUFSIZE)
852 error("%s literal too long/n", q == '"' ? "string" : "character");
853 if (Aflag >= 2 && q == '"' && n > 509)
854 warning("more than 509 characters in a string literal/n");
855 if (Aflag >= 2 && nbad > 0)
856 warning("%s literal contains non-portable characters/n",
857 q == '"' ? "string" : "character");
858 return cl;
859 }
// comments on string literal DFA, in lex.c
156 int gettok(void) {
........
370 case '"': {
371 char *s = scon(*--cp, cput, cbuf); // s points to cbuf[] or wcbuf[]
372 tval.type = array(chartype, s - cbuf, 0); // !! array(widechar, s - wcbuf, 0) for wide string literal
373 tval.u.c.v.p = cbuf; // !! no string copy (1)
374 tsym = &tval;
375 return SCON;
376 }
// comments on literal string expression, in expr.c
339 static Tree primary(void) {
340 Tree p;
341
342 assert(t != '(');
343 switch (t) {
344 case ICON:
....
348 case SCON: if (ischar(tsym->type->type)) // !!! for ASCII character, tsym->type is a "char"
349 tsym->u.c.v.p = stringn(tsym->u.c.v.p, tsym->type->size); // !!! string copy here (2)
350 else // !!! wide string character, tsym->type is a "widechar "
351 tsym->u.c.v.p = memcpy(allocate(tsym->type->size, PERM), tsym->u.c.v.p, tsym->type-> size);
352 tsym = constant(tsym->type, tsym->u.c.v);
353 if (tsym->u.c.loc == NULL)
354 tsym->u.c.loc = genident(STATIC, tsym->type, GLOBAL);
355 p = idtree(tsym->u.c.loc); break;
[1] invalid definition in c, but valid in c++, no error reported because afte c-preprocessor, it's become "hello /tworld"