comparison dmd/doc.c @ 1587:def7a1d494fd

Merge DMD 1.051
author Christian Kamm <kamm incasoftware de>
date Fri, 06 Nov 2009 23:58:01 +0100
parents eeb8b95ea92e
children 207a8a438dea
comparison
equal deleted inserted replaced
1586:7f728c52e63c 1587:def7a1d494fd
1 1
2 // Compiler implementation of the D programming language 2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2008 by Digital Mars 3 // Copyright (c) 1999-2009 by Digital Mars
4 // All Rights Reserved 4 // All Rights Reserved
5 // written by Walter Bright 5 // written by Walter Bright
6 // http://www.digitalmars.com 6 // http://www.digitalmars.com
7 // License for redistribution is by either the Artistic License 7 // License for redistribution is by either the Artistic License
8 // in artistic.txt, or the GNU General Public License in gnu.txt. 8 // in artistic.txt, or the GNU General Public License in gnu.txt.
31 #include "module.h" 31 #include "module.h"
32 #include "scope.h" 32 #include "scope.h"
33 #include "hdrgen.h" 33 #include "hdrgen.h"
34 #include "doc.h" 34 #include "doc.h"
35 #include "mtype.h" 35 #include "mtype.h"
36 #include "utf.h"
36 37
37 struct Escape 38 struct Escape
38 { 39 {
39 const char *strings[256]; 40 const char *strings[256];
40 41
87 88
88 int cmp(const char *stringz, void *s, size_t slen); 89 int cmp(const char *stringz, void *s, size_t slen);
89 int icmp(const char *stringz, void *s, size_t slen); 90 int icmp(const char *stringz, void *s, size_t slen);
90 int isDitto(unsigned char *comment); 91 int isDitto(unsigned char *comment);
91 unsigned char *skipwhitespace(unsigned char *p); 92 unsigned char *skipwhitespace(unsigned char *p);
92 unsigned skiptoident(OutBuffer *buf, unsigned i); 93 unsigned skiptoident(OutBuffer *buf, size_t i);
93 unsigned skippastident(OutBuffer *buf, unsigned i); 94 unsigned skippastident(OutBuffer *buf, size_t i);
94 unsigned skippastURL(OutBuffer *buf, unsigned i); 95 unsigned skippastURL(OutBuffer *buf, size_t i);
95 void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset); 96 void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset);
96 void highlightCode(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset); 97 void highlightCode(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset);
97 void highlightCode2(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset); 98 void highlightCode2(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset);
98 Argument *isFunctionParameter(Dsymbol *s, unsigned char *p, unsigned len); 99 Argument *isFunctionParameter(Dsymbol *s, unsigned char *p, unsigned len);
100
101 int isIdStart(unsigned char *p);
102 int isIdTail(unsigned char *p);
103 int utfStride(unsigned char *p);
99 104
100 static unsigned char ddoc_default[] = "\ 105 static unsigned char ddoc_default[] = "\
101 DDOC = <html><head>\n\ 106 DDOC = <html><head>\n\
102 <META http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n\ 107 <META http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n\
103 <title>$(TITLE)</title>\n\ 108 <title>$(TITLE)</title>\n\
236 dc->pescapetable = &escapetable; 241 dc->pescapetable = &escapetable;
237 242
238 // Generate predefined macros 243 // Generate predefined macros
239 244
240 // Set the title to be the name of the module 245 // Set the title to be the name of the module
241 { char *p = toPrettyChars(); 246 { const char *p = toPrettyChars();
242 Macro::define(&macrotable, (unsigned char *)"TITLE", 5, (unsigned char *)p, strlen(p)); 247 Macro::define(&macrotable, (unsigned char *)"TITLE", 5, (unsigned char *)p, strlen(p));
243 } 248 }
244 249
245 time_t t; 250 time_t t;
246 time(&t); 251 time(&t);
672 buf->writestring("static "); 677 buf->writestring("static ");
673 if (d->isConst()) 678 if (d->isConst())
674 buf->writestring("const "); 679 buf->writestring("const ");
675 #if DMDV2 680 #if DMDV2
676 if (d->isInvariant()) 681 if (d->isInvariant())
677 buf->writestring("invariant "); 682 buf->writestring("immutable ");
678 #endif 683 #endif
679 if (d->isFinal()) 684 if (d->isFinal())
680 buf->writestring("final "); 685 buf->writestring("final ");
681 if (d->isSynchronized()) 686 if (d->isSynchronized())
682 buf->writestring("synchronized "); 687 buf->writestring("synchronized ");
946 951
947 void DocComment::parseSections(unsigned char *comment) 952 void DocComment::parseSections(unsigned char *comment)
948 { unsigned char *p; 953 { unsigned char *p;
949 unsigned char *pstart; 954 unsigned char *pstart;
950 unsigned char *pend; 955 unsigned char *pend;
951 unsigned char *q;
952 unsigned char *idstart; 956 unsigned char *idstart;
953 unsigned idlen; 957 unsigned idlen;
954 958
955 unsigned char *name = NULL; 959 unsigned char *name = NULL;
956 unsigned namelen = 0; 960 unsigned namelen = 0;
961 { 965 {
962 p = skipwhitespace(p); 966 p = skipwhitespace(p);
963 pstart = p; 967 pstart = p;
964 968
965 /* Find end of section, which is ended by one of: 969 /* Find end of section, which is ended by one of:
966 * 'identifier:' 970 * 'identifier:' (but not inside a code section)
967 * '\0' 971 * '\0'
968 */ 972 */
969 idlen = 0; 973 idlen = 0;
974 int inCode = 0;
970 while (1) 975 while (1)
971 { 976 {
972 if (isalpha(*p) || *p == '_') 977 // Check for start/end of a code section
978 if (*p == '-')
973 { 979 {
974 q = p + 1; 980 int numdash = 0;
975 while (isalnum(*q) || *q == '_') 981 while (*p == '-')
976 q++; 982 {
983 ++numdash;
984 p++;
985 }
986 // BUG: handle UTF PS and LS too
987 if (!*p || *p == '\r' || *p == '\n' && numdash >= 3)
988 inCode ^= 1;
989 }
990
991 if (!inCode && isIdStart(p))
992 {
993 unsigned char *q = p + utfStride(p);
994 while (isIdTail(q))
995 q += utfStride(q);
977 if (*q == ':') // identifier: ends it 996 if (*q == ':') // identifier: ends it
978 { idlen = q - p; 997 { idlen = q - p;
979 idstart = p; 998 idstart = p;
980 for (pend = p; pend > pstart; pend--) 999 for (pend = p; pend > pstart; pend--)
981 { if (pend[-1] == '\n') 1000 { if (pend[-1] == '\n')
1139 1158
1140 buf->writestring("$(DDOC_PARAMS \n"); 1159 buf->writestring("$(DDOC_PARAMS \n");
1141 while (p < pend) 1160 while (p < pend)
1142 { 1161 {
1143 // Skip to start of macro 1162 // Skip to start of macro
1144 for (; 1; p++) 1163 while (1)
1145 { 1164 {
1146 switch (*p) 1165 switch (*p)
1147 { 1166 {
1148 case ' ': 1167 case ' ':
1149 case '\t': 1168 case '\t':
1169 p++;
1150 continue; 1170 continue;
1151 1171
1152 case '\n': 1172 case '\n':
1153 p++; 1173 p++;
1154 goto Lcont; 1174 goto Lcont;
1155 1175
1156 default: 1176 default:
1157 if (!(isalpha(*p) || *p == '_')) 1177 if (isIdStart(p))
1158 { 1178 break;
1159 if (namelen) 1179 if (namelen)
1160 goto Ltext; // continuation of prev macro 1180 goto Ltext; // continuation of prev macro
1161 goto Lskipline; 1181 goto Lskipline;
1162 }
1163 break;
1164 } 1182 }
1165 break; 1183 break;
1166 } 1184 }
1167 tempstart = p; 1185 tempstart = p;
1168 1186
1169 while (isalnum(*p) || *p == '_') 1187 while (isIdTail(p))
1170 p++; 1188 p += utfStride(p);
1171 templen = p - tempstart; 1189 templen = p - tempstart;
1172 1190
1173 while (*p == ' ' || *p == '\t') 1191 while (*p == ' ' || *p == '\t')
1174 p++; 1192 p++;
1175 1193
1267 unsigned textlen; 1285 unsigned textlen;
1268 1286
1269 while (p < pend) 1287 while (p < pend)
1270 { 1288 {
1271 // Skip to start of macro 1289 // Skip to start of macro
1272 for (; 1; p++) 1290 while (1)
1273 { 1291 {
1274 if (p >= pend) 1292 if (p >= pend)
1275 goto Ldone; 1293 goto Ldone;
1276 switch (*p) 1294 switch (*p)
1277 { 1295 {
1278 case ' ': 1296 case ' ':
1279 case '\t': 1297 case '\t':
1298 p++;
1280 continue; 1299 continue;
1281 1300
1282 case '\n': 1301 case '\n':
1283 p++; 1302 p++;
1284 goto Lcont; 1303 goto Lcont;
1285 1304
1286 default: 1305 default:
1287 if (!(isalpha(*p) || *p == '_')) 1306 if (isIdStart(p))
1288 { 1307 break;
1289 if (namelen) 1308 if (namelen)
1290 goto Ltext; // continuation of prev macro 1309 goto Ltext; // continuation of prev macro
1291 goto Lskipline; 1310 goto Lskipline;
1292 }
1293 break;
1294 } 1311 }
1295 break; 1312 break;
1296 } 1313 }
1297 tempstart = p; 1314 tempstart = p;
1298 1315
1299 while (1) 1316 while (1)
1300 { 1317 {
1301 if (p >= pend) 1318 if (p >= pend)
1302 goto Ldone; 1319 goto Ldone;
1303 if (!(isalnum(*p) || *p == '_')) 1320 if (!isIdTail(p))
1304 break; 1321 break;
1305 p++; 1322 p += utfStride(p);
1306 } 1323 }
1307 templen = p - tempstart; 1324 templen = p - tempstart;
1308 1325
1309 while (1) 1326 while (1)
1310 { 1327 {
1484 * start of identifier 1501 * start of identifier
1485 * beginning of next line 1502 * beginning of next line
1486 * end of buf 1503 * end of buf
1487 */ 1504 */
1488 1505
1489 unsigned skiptoident(OutBuffer *buf, unsigned i) 1506 unsigned skiptoident(OutBuffer *buf, size_t i)
1490 { 1507 {
1491 for (; i < buf->offset; i++) 1508 while (i < buf->offset)
1492 { 1509 { dchar_t c;
1493 // BUG: handle unicode alpha's 1510
1494 unsigned char c = buf->data[i]; 1511 size_t oi = i;
1495 if (isalpha(c) || c == '_') 1512 if (utf_decodeChar((unsigned char *)buf->data, buf->offset, &i, &c))
1513 /* Ignore UTF errors, but still consume input
1514 */
1496 break; 1515 break;
1497 if (c == '\n') 1516 if (c >= 0x80)
1498 break; 1517 {
1518 if (!isUniAlpha(c))
1519 continue;
1520 }
1521 else if (!(isalpha(c) || c == '_' || c == '\n'))
1522 continue;
1523 i = oi;
1524 break;
1499 } 1525 }
1500 return i; 1526 return i;
1501 } 1527 }
1502 1528
1503 /************************************************ 1529 /************************************************
1504 * Scan forward past end of identifier. 1530 * Scan forward past end of identifier.
1505 */ 1531 */
1506 1532
1507 unsigned skippastident(OutBuffer *buf, unsigned i) 1533 unsigned skippastident(OutBuffer *buf, size_t i)
1508 { 1534 {
1509 for (; i < buf->offset; i++) 1535 while (i < buf->offset)
1510 { 1536 { dchar_t c;
1511 // BUG: handle unicode alpha's 1537
1512 unsigned char c = buf->data[i]; 1538 size_t oi = i;
1513 if (!(isalnum(c) || c == '_')) 1539 if (utf_decodeChar((unsigned char *)buf->data, buf->offset, &i, &c))
1540 /* Ignore UTF errors, but still consume input
1541 */
1514 break; 1542 break;
1543 if (c >= 0x80)
1544 {
1545 if (isUniAlpha(c))
1546 continue;
1547 }
1548 else if (isalnum(c) || c == '_')
1549 continue;
1550 i = oi;
1551 break;
1515 } 1552 }
1516 return i; 1553 return i;
1517 } 1554 }
1518 1555
1519 1556
1523 * Returns: 1560 * Returns:
1524 * i if not a URL 1561 * i if not a URL
1525 * index just past it if it is a URL 1562 * index just past it if it is a URL
1526 */ 1563 */
1527 1564
1528 unsigned skippastURL(OutBuffer *buf, unsigned i) 1565 unsigned skippastURL(OutBuffer *buf, size_t i)
1529 { unsigned length = buf->offset - i; 1566 { unsigned length = buf->offset - i;
1530 unsigned char *p = &buf->data[i]; 1567 unsigned char *p = &buf->data[i];
1531 unsigned j; 1568 unsigned j;
1532 unsigned sawdot = 0; 1569 unsigned sawdot = 0;
1533 1570
1808 } 1845 }
1809 break; 1846 break;
1810 1847
1811 default: 1848 default:
1812 leadingBlank = 0; 1849 leadingBlank = 0;
1813 if (sc && !inCode && (isalpha(c) || c == '_')) 1850 if (sc && !inCode && isIdStart(&buf->data[i]))
1814 { unsigned j; 1851 { unsigned j;
1815 1852
1816 j = skippastident(buf, i); 1853 j = skippastident(buf, i);
1817 if (j > i) 1854 if (j > i)
1818 { 1855 {
1879 size_t len = strlen(se); 1916 size_t len = strlen(se);
1880 buf->remove(i, 1); 1917 buf->remove(i, 1);
1881 i = buf->insert(i, se, len); 1918 i = buf->insert(i, se, len);
1882 i--; // point to ';' 1919 i--; // point to ';'
1883 } 1920 }
1884 else if (isalpha(c) || c == '_') 1921 else if (isIdStart(&buf->data[i]))
1885 { unsigned j; 1922 { unsigned j;
1886 1923
1887 j = skippastident(buf, i); 1924 j = skippastident(buf, i);
1888 if (j > i) 1925 if (j > i)
1889 { 1926 {
2015 break; 2052 break;
2016 } 2053 }
2017 return s; 2054 return s;
2018 } 2055 }
2019 2056
2057 /****************************************
2058 * Determine if p points to the start of an identifier.
2059 */
2060
2061 int isIdStart(unsigned char *p)
2062 {
2063 unsigned c = *p;
2064 if (isalpha(c) || c == '_')
2065 return 1;
2066 if (c >= 0x80)
2067 { size_t i = 0;
2068 if (utf_decodeChar(p, 4, &i, &c))
2069 return 0; // ignore errors
2070 if (isUniAlpha(c))
2071 return 1;
2072 }
2073 return 0;
2074 }
2075
2076 /****************************************
2077 * Determine if p points to the rest of an identifier.
2078 */
2079
2080 int isIdTail(unsigned char *p)
2081 {
2082 unsigned c = *p;
2083 if (isalnum(c) || c == '_')
2084 return 1;
2085 if (c >= 0x80)
2086 { size_t i = 0;
2087 if (utf_decodeChar(p, 4, &i, &c))
2088 return 0; // ignore errors
2089 if (isUniAlpha(c))
2090 return 1;
2091 }
2092 return 0;
2093 }
2094
2095 /*****************************************
2096 * Return number of bytes in UTF character.
2097 */
2098
2099 int utfStride(unsigned char *p)
2100 {
2101 unsigned c = *p;
2102 if (c < 0x80)
2103 return 1;
2104 size_t i = 0;
2105 utf_decodeChar(p, 4, &i, &c); // ignore errors, but still consume input
2106 return i;
2107 }