LINUX.ORG.RU

[GCC] Как перекодировать строки в другую кодировку перед компиляцией?

 


0

0

Здравствуйте! Нужно перекодировать строки записанные в «кавычках» или одиночным 'символом' в другую кодировку не совместимую с ныне существующими стандартными, перед непосредственной компиляцией исходника компилятором GCC. Существует ли какое-то решение такой проблемы? не через одно место..

Мой вариант через одно место таков: перед компиляцией на исходник натравляется перл скрипт, находит там строки в «кавычках», или одиночные 'символы', перекодирует их, а потом возвращает компилятору. Идея эта более-менее работает, но в некоторых случаях без глубокого синтаксического анализа довольно трудно определить строку или одиночный символ в исходнике, поэтому могут быть ошибки..

Как быть?

ЗЫ: вот что-то такое сейчас у меня используется:

#!/usr/bin/perl -w
use strict;
use Encode qw(encode);
use open ":locale", OUT => '';

my @tbl = (
  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xF7, 0xEF, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0x20,
  0x20, 0x20, 0x20, 0x20, 0xFE, 0xFD, 0xC8, 0xC9, 0xCA, 0xCB, 0xCD, 0xCE, 0xCF, 0x20, 0xD9, 0xDA,
  0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
  0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
  0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x20, 0x5D, 0x5E, 0x5F,
  0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
  0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0xE9, 0x20,
  0x41, 0xA0, 0x42, 0xA1, 0xE0, 0x45, 0xA3, 0xA4, 0xA5, 0xA6, 0x4B, 0xA7, 0x4D, 0x48, 0x4F, 0xA8,
  0x50, 0x43, 0x54, 0xA9, 0xAA, 0x58, 0xE1, 0xAB, 0xAC, 0xE2, 0xAD, 0xAE, 0x62, 0xAF, 0xB0, 0xB1,
  0x61, 0xB2, 0xB3, 0xB4, 0xE3, 0x65, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0x6F, 0xBE,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xFF, 0x20, 0x20, 0x20, 0x20,
  0x70, 0x63, 0xBF, 0x79, 0xE4, 0x78, 0xE5, 0xC0, 0xC1, 0xE6, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
  0xA2, 0xB5, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xEF, 0x4E, 0x4E, 0x20, 0xCC, 0xEE, 0x20, 0x20
);

open(F, $ARGV[0]) || die("$!\n");
while (<F>) {
  s{"(((\\")|[^"])*)"}{
    '"'.translate($1).'"';
  }eg;
  print $_;
}
close(F);

sub translate {
  my $s = encode('ibm866', $_[0]);
  $s =~ s/\\(["\\])/$1/g; # отменить экранирование спец печатаемых символов
  $s =~ s{\\(\d+)}{chr(oct($1))}eg; # отменить экранирование непечатаемых символов
  $s =~ s{(.)}{ pack("C",$tbl[ord($1)]) }eg;
  $s =~ s/"/\\"/g; # экранировать кавычки
  return $s;
};

Как быть?

Хранить строки во внешнем файле.

Deleted
()

Если надо UTF-8 получить в результате, то ВСЮ программу перекодировать в нужную кодировку. Всё в программе, кроме строк, имеет коды меньше 128 и оно останется тем же самым.

anonymous
()
Ответ на: комментарий от anonymous

Комментарии могут быть не на английском.

Свой модуль для iconv, чтобы скомпилировать программу - это чересчур круто, я бы программными средствами попытался обойтись. Или выделить все нужные строки в отдельный хедер, который и препроцессировать.

Legioner ★★★★★
()
Ответ на: комментарий от anonymous

> Всё в программе, кроме строк, имеет коды меньше 128 и оно останется тем же самым.
в кодировке в которую мне надо перевести даже символ '{' имеет код отличный от ascii. Одинаковы только печатные символы латинского алфавита и арабские цифры. Я сам так думал сначала сделать, но..

anterior
() автор топика
Ответ на: комментарий от anterior

>в кодировке в которую мне надо перевести даже символ '{' имеет код отличный от ascii.

это что за наркомания такая?

Love5an
()
Ответ на: комментарий от ananas

> создать свой модуль для iconv
тоже так хотел сделать, но как эти модули создавать совсем непонятно. В поиске толком никакой информации про это не нашёл..

anterior
() автор топика
Ответ на: комментарий от anterior

> > это что за наркомания такая?

Это кодировка используемая ЖК-модулем WH1602B. Под него я подстраиваюсь:)


1) как уже подсказали - строки в отдельный файл.
2) проводить конвертацию строки в рантайме перед ее использованием.

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

> 1) как уже подсказали - строки в отдельный файл.
Неудобно исходный код будет читать, не хочется так делать.

Ех.. похоже придётся использовать свой perl-скрипт, он хоть и может ошибаться, но большинство случаев вроде покрывает..

anterior
() автор топика
Ответ на: комментарий от andreyu

> 2) проводить конвертацию строки в рантайме перед ее использованием.

А почему бы не макросом во время препроцессинга?

frey ★★
()
Ответ на: комментарий от frey

> А почему бы не макросом во время препроцессинга?

Да, исчитал документацию по препроцессору. Помоему это не возможно, не так ли? Вот если бы препроцессор давал возможность обрабатывать данные через макрос используя вызов внешней программы..

anterior
() автор топика

Если я правильно понимаю, то задача сводится фактически к переводу текста в строках программы. Только вместо иностранного языка выступает непонятная для человека кодировка. Если так, то такие технологии отработаны, например как это реализовано в Qt и др.

anonymous
()
Ответ на: комментарий от ananas

Метод грязного хака..

Нашёл оригинальный способ создать модуль не читая мануал. Там всё равно хоть что-то и понятно, но очень смутно и туманно...

Поэтому делал так: взял либу ibm866.so, открыл её в шестнадцатеричном редакторе, нашёл там таблицу которая отвечает за перекодировку, заменил на ту что у меня в скрипте... Потом заменил оригинальный ibm866.so этой хакнутой либой (для теста), и вуаля! РАБОТАЕТ!!!!!!!!!!!))))))))))))

anterior
() автор топика
Ответ на: Метод грязного хака.. от anterior

как вариант - посмотри на iconvdata/ в исходниках glibc. там код достаточно тривиальный, и добавить свою кодировку можно достаточно просто

ananas ★★★★★
()
Ответ на: комментарий от ananas

Да, я смотрел. Вот например файл ibm866.c, если его посмотреть там указана строка:

/* Get the conversion table.  */
#define TABLES <ibm866.h>

А вот где достать ibm866.h я не смог понять где этот файл находится. Обыскал весь архив с glibc, гуглом пытался.. поиск по содержимому файла тоже ничего не дал..

?? не знаю..

anterior
() автор топика
Ответ на: комментарий от ananas

Да действительно, надо было по-внимательней изучить исходники glibc. Там была папка с map-файлами. У них несложное содержание, добавил туда свой. И соответствующий .c файл добавил. Ну и всё, скомпилилось:)

Большое спасибо за помощь!

anterior
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.