2013-07-15 9 views
5

Mam kod, który jeśli został wykonany z monit wierszowy wewnątrz emacs uruchomić bez błędu. Gdybym zaczął od SBCL monit, mam błąd:kodowanie sbcl tylko po uruchomieniu z monitu?

* (ei:proc-file "BRAvESP000.log" "lixo") 

debugger invoked on a SB-INT:STREAM-ENCODING-ERROR: 
    :UTF-8 stream encoding error on 
    #<SB-SYS:FD-STREAM for "file /Users/arademaker/work/IBM/scolapp/lixo" 
    {10049E8FF3}>: 

    the character with code 55357 cannot be encoded. 

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL. 

restarts (invokable by number or by possibly-abbreviated name): 
    0: [OUTPUT-NOTHING ] Skip output of this character. 
    1: [OUTPUT-REPLACEMENT] Output replacement string. 
    2: [ABORT    ] Exit debugger, returning to top level. 

(SB-IMPL::STREAM-ENCODING-ERROR-AND-HANDLE #<SB-SYS:FD-STREAM for "file /Users/arademaker/work/IBM/scolapp/lixo" {10049E8FF3}> 55357) 
0] 

tajemnicą jest, że w obu przypadkach używam tego samego SBCL 1.1.8 i tę samą maszynę, Mac OS 10.8.4. Dowolny pomysł?

Kod:

(defun proc-file (filein fileout &key (fn-convert #'identity)) 
    (with-open-file (fout fileout 
        :direction :output 
        :if-exists :supersede 
        :external-format :utf8) 
    (with-open-file (fin filein :external-format :utf8) 
     (loop for line = (read-line fin nil) 
     while line 
     do 
     (handler-case 
     (let* ((line (ppcre:regex-replace "^.*{jsonTweet=" line "{\"jsonTweet\":")) 
       (data (gethash "jsonTweet" (yason:parse line)))) 
      (yason:encode (funcall fn-convert (yason:parse data)) fout) 
      (format fout "~%")) 
      (end-of-file() 
     (format *standard-output* "Error[~a]: ~a~%" filein line))))))) 
+1

Sugeruję zacząć od zakładając, to nie jest problem Yason - dowiemy się szybko, jeśli tak jest - i dodaj następujący kod do swojego kodu: '(format * standard-output *" ~ & ~ {~ x ~^~} "(lista znaków na mapie '))'. Czy ostatnia linia w niepowodzeniu jest taka sama jak odpowiednia linia w środowisku SLIME? –

+1

Być może istnieją pliki o nazwie BRAvESP000.log w więcej niż jednym katalogu, a bieżący katalog jest inny, jeśli jesteś w SLIME lub jeśli uruchamiasz SBCL ręcznie. Wypróbuj bezwzględne ścieżki. – acelent

+0

Jeśli kod postaci nie jest pomyłką, należy do zakresu liczb zastępczych Unicode. Nie są to znaki o kodowaniu UTF-8, są zarezerwowane do użytku z UTF-16. Oto moje przypuszczenie: istnieje nowoczesna tradycja w projektowaniu stron internetowych do używania prywatnych znaków płaskich wraz ze specjalną czcionką służącą jako ikony (takie jak różne strzałki, pociski itd.). W szczególności robi to Twitter (podobnie jak na przykład Github). Jest to sposób na zapisanie strony HTML przy ładowaniu obrazów (ponieważ są to kontury wektorowe ze specjalnej czcionki). Wyobrażam sobie, że Emacs radzi sobie z nimi przed wysłaniem. –

Odpowiedz

1

To prawie na pewno błąd w Yason. JSON wymaga, aby jeśli znak bez znaku BMP został usunięty, jest to wykonywane przez zastępczą parę. Oto prosty przykład z U + 10000 (która jest ewentualnie uniknięciu w json jako „\ ud800 \ udc00”; użyć babel jak konwersja Babla mniej strln)

(map 'list #'char-code (yason:parse "\"\\ud800\\udc00\"")) 
    => (55296 56320) 

Unicode kod punktu 55296 (dziesiętnie) jest rozpocząć dla pary zastępczej i nie powinny się pojawiać, z wyjątkiem jako pary zastępczej w UTF-16. Na szczęście można łatwo obejść przy użyciu Babel do kodowania znaków na UTF-16 i znowu:

(babel:octets-to-string (babel:string-to-octets (yason:parse "\"\\ud800\\udc00\"") :encoding :utf-16le) :encoding :utf-16le) 
    => "" 

powinien być w stanie obejść ten problem poprzez zmianę tej linii:

(yason:encode (funcall fn-convert (yason:parse data)) fout) 

Aby użyj pośredniego ciągu, który konwertujesz do UTF-16 iz powrotem.

(write-sequence 
(babel:octets-to-string 
    (babel:string-to-octets 
    (with-output-to-string (outs) 
    (yason:encode (funcall fn-convert (yason:parse data)) outs)) 
    :encoding :utf-16le) 
    :encoding :utf-16le) 
fout) 

złożyłem poprawkę, która została zaakceptowana to naprawić w Yason:

https://github.com/hanshuebner/yason/commit/4a9bdaae652b7ceea79984e0349a992a5458a0dc

Powiązane problemy