Index: src/branch.c ================================================================== --- src/branch.c +++ src/branch.c @@ -1,7 +1,7 @@ /* -** Copyright (c) 2007 D. Richard Hipp +** Copyright © 2007 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) @@ -355,11 +355,11 @@ cnt++; } if( colorTest ){ const char *zColor = hash_color(zBr); @ <li><span style="background-color: %s(zColor)"> - @ %h(zBr) → %s(zColor)</span></li> + @ %h(zBr) → %s(zColor)</span></li> }else{ @ <li>%z(href("%R/timeline?r=%T",zBr))%h(zBr)</a></li> } } if( cnt ){ Index: src/export.c ================================================================== --- src/export.c +++ src/export.c @@ -1,7 +1,7 @@ /* -** Copyright (c) 2010 D. Richard Hipp +** Copyright © 2010 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) @@ -136,11 +136,11 @@ if( markfile_in!=0 ){ Stmt qb,qc; char line[100]; FILE *f; - f = fopen(markfile_in, "r"); + f = fossil_fopen(markfile_in, "r"); if( f==0 ){ fossil_panic("cannot open %s for reading", markfile_in); } db_prepare(&qb, "INSERT OR IGNORE INTO oldblob VALUES (:rid)"); db_prepare(&qc, "INSERT OR IGNORE INTO oldcommit VALUES (:rid)"); @@ -325,11 +325,11 @@ db_finalize(&q); bag_clear(&vers); if( markfile_out!=0 ){ FILE *f; - f = fopen(markfile_out, "w"); + f = fossil_fopen(markfile_out, "w"); if( f == 0 ){ fossil_panic("cannot open %s for writing", markfile_out); } db_prepare(&q, "SELECT rid FROM oldblob"); while( db_step(&q)==SQLITE_ROW ){ Index: src/file.c ================================================================== --- src/file.c +++ src/file.c @@ -1,7 +1,7 @@ /* -** Copyright (c) 2006 D. Richard Hipp +** Copyright © 2006 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) @@ -32,10 +32,11 @@ /* ** On Windows, include the Platform SDK header file. */ #ifdef _WIN32 +# include <direct.h> # include <windows.h> #endif /* ** The file status information from the most recent stat() call. @@ -68,12 +69,12 @@ }else{ return stat(zFilename, buf); } #else int rc = 0; - char *zMbcs = fossil_utf8_to_mbcs(zFilename); - rc = stat(zMbcs, buf); + wchar_t *zMbcs = fossil_utf8_to_unicode(zFilename); + rc = _wstati64(zMbcs, buf); fossil_mbcs_free(zMbcs); return rc; #endif } @@ -298,13 +299,17 @@ /* ** Wrapper around the access() system call. */ int file_access(const char *zFilename, int flags){ - char *zMbcs = fossil_utf8_to_mbcs(zFilename); - int rc = access(zMbcs, flags); +#ifdef _WIN32 + wchar_t *zMbcs = fossil_utf8_to_unicode(zFilename); + int rc = _waccess(zMbcs, flags); fossil_mbcs_free(zMbcs); +#else + int rc = access(zFilename, flags); +#endif return rc; } /* ** Find an unused filename similar to zBase with zSuffix appended. @@ -389,13 +394,17 @@ /* ** Delete a file. */ void file_delete(const char *zFilename){ - char *z = fossil_utf8_to_mbcs(zFilename); - unlink(z); +#ifdef _WIN32 + wchar_t *z = fossil_utf8_to_unicode(zFilename); + _wunlink(z); fossil_mbcs_free(z); +#else + unlink(zFilename); +#endif } /* ** Create the directory named in the argument, if it does not already ** exist. If forceFlag is 1, delete any prior non-directory object @@ -410,12 +419,12 @@ file_delete(zName); } if( rc!=1 ){ #if defined(_WIN32) int rc; - char *zMbcs = fossil_utf8_to_mbcs(zName); - rc = mkdir(zMbcs); + wchar_t *zMbcs = fossil_utf8_to_unicode(zName); + rc = _wmkdir(zMbcs); fossil_mbcs_free(zMbcs); return rc; #else return mkdir(zName, 0755); #endif @@ -561,24 +570,24 @@ } /* ** Get the current working directory. ** -** On windows, the name is converted from MBCS to UTF8 and all '\\' +** On windows, the name is converted from unicode to UTF8 and all '\\' ** characters are converted to '/'. No conversions are needed on ** unix. */ void file_getcwd(char *zBuf, int nBuf){ #ifdef _WIN32 char *zPwdUtf8; int nPwd; int i; - char zPwd[2000]; - if( getcwd(zPwd, sizeof(zPwd)-1)==0 ){ + wchar_t zPwd[2000]; + if( _wgetcwd(zPwd, sizeof(zPwd)-1)==0 ){ fossil_fatal("cannot find the current working directory."); } - zPwdUtf8 = fossil_mbcs_to_utf8(zPwd); + zPwdUtf8 = fossil_unicode_to_utf8(zPwd); nPwd = strlen(zPwdUtf8); if( nPwd > nBuf-1 ){ fossil_fatal("pwd too big: max %d\n", nBuf-1); } for(i=0; zPwdUtf8[i]; i++) if( zPwdUtf8[i]=='\\' ) zPwdUtf8[i] = '/'; @@ -928,14 +937,14 @@ unsigned int i, j; const char *zDir = "."; int cnt = 0; #if defined(_WIN32) - char zTmpPath[MAX_PATH]; + wchar_t zTmpPath[MAX_PATH]; - if( GetTempPath(sizeof(zTmpPath), zTmpPath) ){ - azDirs[0] = zTmpPath; + if( GetTempPathW(MAX_PATH, zTmpPath) ){ + azDirs[0] = fossil_unicode_to_utf8(zTmpPath); } azDirs[1] = fossil_getenv("TEMP"); azDirs[2] = fossil_getenv("TMP"); #endif @@ -1014,10 +1023,29 @@ return sqlite3_win32_mbcs_to_utf8(zMbcs); #else return (char*)zMbcs; /* No-op on unix */ #endif } + +/* +** Translate Unicode to UTF8. Return a pointer to the translated text. +** Call fossil_mbcs_free() to deallocate any memory used to store the +** returned pointer when done. +*/ +char *fossil_unicode_to_utf8(const void *zUnicode){ +#ifdef _WIN32 + int nByte = WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, 0, 0, 0, 0); + char *zUtf = sqlite3_malloc( nByte ); + if( zUtf==0 ){ + return 0; + } + WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, zUtf, nByte, 0, 0); + return zUtf; +#else + return (char *)zUnicode; /* No-op on unix */ +#endif +} /* ** Translate UTF8 to MBCS for use in system calls. Return a pointer to the ** translated text.. Call fossil_mbcs_free() to deallocate any memory ** used to store the returned pointer when done. @@ -1028,18 +1056,41 @@ return sqlite3_win32_utf8_to_mbcs(zUtf8); #else return (char*)zUtf8; /* No-op on unix */ #endif } + +/* +** Translate UTF8 to unicode for use in system calls. Return a pointer to the +** translated text.. Call fossil_mbcs_free() to deallocate any memory +** used to store the returned pointer when done. +*/ +void *fossil_utf8_to_unicode(const char *zUtf8){ +#ifdef _WIN32 + int nByte = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0); + wchar_t *zUnicode = sqlite3_malloc( nByte * 2 ); + if( zUnicode==0 ){ + return 0; + } + MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nByte); + return zUnicode; +#else + return (void *)zUtf8; /* No-op on unix */ +#endif +} /* ** Return the value of an environment variable as UTF8. */ char *fossil_getenv(const char *zName){ - char *zValue = getenv(zName); #ifdef _WIN32 - if( zValue ) zValue = fossil_mbcs_to_utf8(zValue); + wchar_t *uName = fossil_utf8_to_unicode(zName); + void *zValue = _wgetenv(uName); + fossil_mbcs_free(uName); + if( zValue ) zValue = fossil_unicode_to_utf8(zValue); +#else + char *zValue = getenv(zName); #endif return zValue; } /* @@ -1085,11 +1136,11 @@ /* ** Translate MBCS to UTF8. Return a pointer. Call fossil_mbcs_free() ** to deallocate any memory used to store the returned pointer when done. */ -void fossil_mbcs_free(char *zOld){ +void fossil_mbcs_free(void *zOld){ #ifdef _WIN32 extern void sqlite3_free(void*); sqlite3_free(zOld); #else /* No-op on unix */ @@ -1098,10 +1149,16 @@ /* ** Like fopen() but always takes a UTF8 argument. */ FILE *fossil_fopen(const char *zName, const char *zMode){ - char *zMbcs = fossil_utf8_to_mbcs(zName); - FILE *f = fopen(zMbcs, zMode); - fossil_mbcs_free(zMbcs); +#ifdef _WIN32 + wchar_t *uMode = fossil_utf8_to_unicode(zMode); + wchar_t *uName = fossil_utf8_to_unicode(zName); + FILE *f = _wfopen(uName, uMode); + fossil_mbcs_free(uName); + fossil_mbcs_free(uMode); +#else + FILE *f = fopen(zName, zMode); +#endif return f; } Index: src/import.c ================================================================== --- src/import.c +++ src/import.c @@ -1,7 +1,7 @@ /* -** Copyright (c) 2010 D. Richard Hipp +** Copyright © 2010 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) @@ -732,11 +732,11 @@ verify_all_options(); if( g.argc!=3 && g.argc!=4 ){ usage("REPOSITORY-NAME"); } if( g.argc==4 ){ - pIn = fopen(g.argv[3], "rb"); + pIn = fossil_fopen(g.argv[3], "rb"); }else{ pIn = stdin; fossil_binary_mode(pIn); } if( !incrFlag ){ Index: src/rebuild.c ================================================================== --- src/rebuild.c +++ src/rebuild.c @@ -21,10 +21,19 @@ #include "rebuild.h" #include <assert.h> #include <dirent.h> #include <errno.h> +#ifndef _WIN32 +#define _WDIR DIR +#define _wdirent dirent +#define _wopendir opendir +#define _wreaddir readdir +#define _wclosedir closedir +#define wchar_t char +#endif + /* ** Make changes to the stable part of the schema (the part that is not ** simply deleted and reconstructed on a rebuild) to bring the schema ** up to the latest. */ @@ -818,28 +827,28 @@ /* ** Recursively read all files from the directory zPath and install ** every file read as a new artifact in the repository. */ void recon_read_dir(char *zPath){ - DIR *d; - struct dirent *pEntry; + _WDIR *d; + struct _wdirent *pEntry; Blob aContent; /* content of the just read artifact */ static int nFileRead = 0; - char *zMbcsPath; + wchar_t *zMbcsPath; char *zUtf8Name; - zMbcsPath = fossil_utf8_to_mbcs(zPath); - d = opendir(zMbcsPath); + zMbcsPath = fossil_utf8_to_unicode(zPath); + d = _wopendir(zMbcsPath); if( d ){ - while( (pEntry=readdir(d))!=0 ){ + while( (pEntry=_wreaddir(d))!=0 ){ Blob path; char *zSubpath; if( pEntry->d_name[0]=='.' ){ continue; } - zUtf8Name = fossil_mbcs_to_utf8(pEntry->d_name); + zUtf8Name = fossil_unicode_to_utf8(pEntry->d_name); zSubpath = mprintf("%s/%s", zPath, zUtf8Name); fossil_mbcs_free(zUtf8Name); if( file_isdir(zSubpath)==1 ){ recon_read_dir(zSubpath); } @@ -854,11 +863,11 @@ blob_reset(&aContent); free(zSubpath); fossil_print("\r%d", ++nFileRead); fflush(stdout); } - closedir(d); + _wclosedir(d); }else { fossil_panic("encountered error %d while trying to open \"%s\".", errno, g.argv[3]); } fossil_mbcs_free(zMbcsPath); Index: src/setup.c ================================================================== --- src/setup.c +++ src/setup.c @@ -1,7 +1,7 @@ /* -** Copyright (c) 2007 D. Richard Hipp +** Copyright © 2007 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) @@ -496,38 +496,38 @@ if( fossil_strcmp(zLogin, "developer") ){ char *z1, *z2; z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='developer'"); while( z1 && *z1 ){ inherit[0x7f & *(z1++)] = - "<span class=\"ueditInheritDeveloper\">•</span>"; + "<span class=\"ueditInheritDeveloper\">•</span>"; } free(z2); } if( fossil_strcmp(zLogin, "reader") ){ char *z1, *z2; z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='reader'"); while( z1 && *z1 ){ inherit[0x7f & *(z1++)] = - "<span class=\"ueditInheritReader\">•</span>"; + "<span class=\"ueditInheritReader\">•</span>"; } free(z2); } if( fossil_strcmp(zLogin, "anonymous") ){ char *z1, *z2; z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='anonymous'"); while( z1 && *z1 ){ inherit[0x7f & *(z1++)] = - "<span class=\"ueditInheritAnonymous\">•</span>"; + "<span class=\"ueditInheritAnonymous\">•</span>"; } free(z2); } if( fossil_strcmp(zLogin, "nobody") ){ char *z1, *z2; z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='nobody'"); while( z1 && *z1 ){ inherit[0x7f & *(z1++)] = - "<span class=\"ueditInheritNobody\">•</span>"; + "<span class=\"ueditInheritNobody\">•</span>"; } free(z2); } /* Begin generating the page @@ -662,30 +662,30 @@ @ and reset user passwords. Both automatically get all other privileges @ listed below. Use these two settings with discretion. @ </p></li> @ @ <li><p> - @ The "<span class="ueditInheritNobody"><big>•</big></span>" mark + @ The "<span class="ueditInheritNobody"><big>•</big></span>" mark @ indicates the privileges of <span class="usertype">nobody</span> that @ are available to all users regardless of whether or not they are logged in. @ </p></li> @ @ <li><p> - @ The "<span class="ueditInheritAnonymous"><big>•</big></span>" mark + @ The "<span class="ueditInheritAnonymous"><big>•</big></span>" mark @ indicates the privileges of <span class="usertype">anonymous</span> that @ are inherited by all logged-in users. @ </p></li> @ @ <li><p> - @ The "<span class="ueditInheritDeveloper"><big>•</big></span>" mark + @ The "<span class="ueditInheritDeveloper"><big>•</big></span>" mark @ indicates the privileges of <span class="usertype">developer</span> that @ are inherited by all users with the @ <span class="capability">Developer</span> privilege. @ </p></li> @ @ <li><p> - @ The "<span class="ueditInheritReader"><big>•</big></span>" mark + @ The "<span class="ueditInheritReader"><big>•</big></span>" mark @ indicates the privileges of <span class="usertype">reader</span> that @ are inherited by all users with the <span class="capability">Reader</span> @ privilege. @ </p></li> @ @@ -1616,16 +1616,16 @@ style_header("Raw SQL Commands"); @ <p><b>Caution:</b> There are no restrictions on the SQL that can be @ run by this page. You can do serious and irrepairable damage to the @ repository. Proceed with extreme caution.</p> @ - @ <p>Database names:<ul><li>repository → %s(db_name("repository")) + @ <p>Database names:<ul><li>repository → %s(db_name("repository")) if( g.configOpen ){ - @ <li>config → %s(db_name("configdb")) + @ <li>config → %s(db_name("configdb")) } if( g.localOpen ){ - @ <li>local-checkout → %s(db_name("localdb")) + @ <li>local-checkout → %s(db_name("localdb")) } @ </ul></p> @ @ <form method="post" action="%s(g.zTop)/admin_sql"> login_insert_csrf_secret(); Index: src/timeline.c ================================================================== --- src/timeline.c +++ src/timeline.c @@ -1,7 +1,7 @@ /* -** Copyright (c) 2007 D. Richard Hipp +** Copyright © 2007 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) @@ -318,11 +318,11 @@ @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> }else{ @ <td class="timelineTableCell"> } if( pGraph && zType[0]!='c' ){ - @ • + @ • } if( zType[0]=='c' ){ hyperlink_to_uuid(zUuid); if( isLeaf ){ if( db_exists("SELECT 1 FROM tagxref" @@ -436,16 +436,16 @@ @ %z(xhref("target='diffwindow'","%R/artifact/%S",zNew)) @ [view]</a></li> }else if( isDel ){ @ <li> %h(zFilename) (deleted)</li> }else if( fossil_strcmp(zOld,zNew)==0 && zOldName!=0 ){ - @ <li> %h(zOldName) → %h(zFilename) + @ <li> %h(zOldName) → %h(zFilename) @ %z(xhref("target='diffwindow'","%R/artifact/%S",zNew)) @ [view]</a></li> }else{ if( zOldName!=0 ){ - @ <li> %h(zOldName) → %h(zFilename) + @ <li> %h(zOldName) → %h(zFilename) }else{ @ <li> %h(zFilename) } @ %z(xhref("target='diffwindow'","%R/fdiff?v1=%S&v2=%S",zOld,zNew)) @ [diff]</a></li> Index: src/translate.c ================================================================== --- src/translate.c +++ src/translate.c @@ -1,7 +1,7 @@ /* -** Copyright (c) 2002 D. Richard Hipp +** Copyright © 2002 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) @@ -76,17 +76,34 @@ char c1, c2; /* Characters used to start a comment */ int lastWasEq = 0; /* True if last non-whitespace character was "=" */ int lastWasComma = 0; /* True if last non-whitespace character was "," */ char zLine[2000]; /* A single line of input */ char zOut[4000]; /* The input line translated into appropriate output */ + int isFirstline = 1; /* True if this is the first line */ c1 = c2 = '-'; while( fgets(zLine, sizeof(zLine), in) ){ + if (isFirstline) { + static const char bom[] = { 0xEF, 0xBB, 0xBF }; + if( memcmp(zLine, bom, 3)==0 ) { + memmove(zLine, zLine+3, sizeof(zLine)-3); + } + isFirstline = 0; + } for(i=0; zLine[i] && isspace(zLine[i]); i++){} if( zLine[i]!='@' ){ if( inPrint || inStr ) end_block(out); - fprintf(out,"%s",zLine); + for(i=0,j=0; zLine[i]; i++){ + if (128 <= (unsigned char)zLine[i]) { + sprintf(&zOut[j], "\\0x%.2X", zLine[i] & 0xFF); + j += 5; + } else { + zOut[j++] = zLine[i]; + } + } + zOut[j] = 0; + fprintf(out,"%s",zOut); /* 0123456789 12345 */ if( strncmp(zLine, "/* @-comment: ", 14)==0 ){ c1 = zLine[14]; c2 = zLine[15]; } @@ -110,11 +127,16 @@ for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){ if( zLine[i]==c1 && (c2==' ' || zLine[i+1]==c2) ){ omitline = 1; break; } if( zLine[i]=='"' || zLine[i]=='\\' ){ zOut[j++] = '\\'; } - zOut[j++] = zLine[i]; + if (128 <= (unsigned char)zLine[i]) { + sprintf(&zOut[j], "\\0x%.2X", zLine[i] & 0xFF); + j += 5; + } else { + zOut[j++] = zLine[i]; + } } while( j>0 && isspace(zOut[j-1]) ){ j--; } zOut[j] = 0; if( j<=0 && omitline ){ fprintf(out,"\n"); @@ -134,11 +156,16 @@ i++; if( isspace(zLine[i]) ){ i++; } indent = i; for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){ if( zLine[i]=='"' || zLine[i]=='\\' ){ zOut[j++] = '\\'; } - zOut[j++] = zLine[i]; + if (128 <= (unsigned char)zLine[i]) { + sprintf(&zOut[j], "\\0x%.2X", zLine[i] & 0xFF); + j += 5; + } else { + zOut[j++] = zLine[i]; + } if( zLine[i]!='%' || zLine[i+1]=='%' || zLine[i+1]==0 ) continue; for(nC=1; zLine[i+nC] && zLine[i+nC]!='('; nC++){} if( zLine[i+nC]!='(' || !isalpha(zLine[i+nC-1]) ) continue; while( --nC ) zOut[j++] = zLine[++i]; zArg[nArg++] = ','; Index: src/vfile.c ================================================================== --- src/vfile.c +++ src/vfile.c @@ -25,10 +25,19 @@ #include "dirent.h" #else #include <dirent.h> #endif +#ifndef _WIN32 +#define _WDIR DIR +#define _wdirent dirent +#define _wopendir opendir +#define _wreaddir readdir +#define _wclosedir closedir +#define wchar_t char +#endif + /* ** The input is guaranteed to be a 40-character well-formed UUID. ** Find its rid. */ int fast_uuid_to_rid(const char *zUuid){ @@ -381,18 +390,18 @@ ** Any files or directories that match the glob pattern pIgnore are ** excluded from the scan. Name matching occurs after the first ** nPrefix characters are elided from the filename. */ void vfile_scan(Blob *pPath, int nPrefix, int allFlag, Glob *pIgnore){ - DIR *d; + _WDIR *d; int origSize; const char *zDir; - struct dirent *pEntry; + struct _wdirent *pEntry; int skipAll = 0; static Stmt ins; static int depth = 0; - char *zMbcs; + wchar_t *zMbcs; origSize = blob_size(pPath); if( pIgnore ){ blob_appendf(pPath, "/"); if( glob_match(pIgnore, &blob_str(pPath)[nPrefix+1]) ) skipAll = 1; @@ -407,22 +416,22 @@ ); } depth++; zDir = blob_str(pPath); - zMbcs = fossil_utf8_to_mbcs(zDir); - d = opendir(zMbcs); + zMbcs = fossil_utf8_to_unicode(zDir); + d = _wopendir(zMbcs); if( d ){ - while( (pEntry=readdir(d))!=0 ){ + while( (pEntry=_wreaddir(d))!=0 ){ char *zPath; char *zUtf8; if( pEntry->d_name[0]=='.' ){ if( !allFlag ) continue; if( pEntry->d_name[1]==0 ) continue; if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue; } - zUtf8 = fossil_mbcs_to_utf8(pEntry->d_name); + zUtf8 = fossil_unicode_to_utf8(pEntry->d_name); blob_appendf(pPath, "/%s", zUtf8); fossil_mbcs_free(zUtf8); zPath = blob_str(pPath); if( glob_match(pIgnore, &zPath[nPrefix+1]) ){ /* do nothing */ @@ -435,11 +444,11 @@ db_step(&ins); db_reset(&ins); } blob_resize(pPath, origSize); } - closedir(d); + _wclosedir(d); } fossil_mbcs_free(zMbcs); depth--; if( depth==0 ){ Index: src/wikiformat.c ================================================================== --- src/wikiformat.c +++ src/wikiformat.c @@ -1,7 +1,7 @@ /* -** Copyright (c) 2007 D. Richard Hipp +** Copyright © 2007 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) @@ -1190,11 +1190,11 @@ p->state |= AT_NEWLINE; break; } case TOKEN_BUL_LI: { if( inlineOnly ){ - blob_append(p->pOut, " • ", -1); + blob_append(p->pOut, " • ", -1); }else{ if( p->wikiList!=MARKUP_UL ){ if( p->wikiList ){ popStackToTag(p, p->wikiList); } @@ -1410,18 +1410,18 @@ p->state &= ~ALLOW_WIKI; for (vAttrIdx = 0; vAttrIdx < markup.nAttr; vAttrIdx++){ if( markup.aAttr[vAttrIdx].iACode == ATTR_ID ){ p->zVerbatimId = markup.aAttr[0].zValue; }else if( markup.aAttr[vAttrIdx].iACode == ATTR_TYPE ){ - blob_appendf(p->pOut, "<pre name='code' class='%s'>", + blob_appendf(p->pOut, "<pre name=\"code\" class=\"%s\">", markup.aAttr[vAttrIdx].zValue); vAttrDidAppend=1; } } if( !vAttrDidAppend ) { endAutoParagraph(p); - blob_append(p->pOut, "<pre class='verbatim'>",-1); + blob_append(p->pOut, "<pre class=\"verbatim\">",-1); } p->wantAutoParagraph = 0; }else if( markup.iType==MUTYPE_LI ){ if( backupToType(p, MUTYPE_LIST)==0 ){