Использование m4 для преобразования строки в кодовые точки ASCII

Это должно быть возможно, но, поскольку я новичок в m4, я не уверен, как это сделать или как написать алгоритм для этого (в m4).

редактировать:

Только что решил, во всяком случае для дальнейшего использования, у меня есть серия символов, их нужно перевести в эквивалентные им кодовые точки ASCII, например

ascii(-{COLON}-, -{:}-) => #define TKN_COLON 58

2 ответа

Решение

Я сделал это с помощью следующего раздела кода

divert(-1)
changequote(-{,}-)
changecom(/*,*/)
define(-{ascii}-,-{#define TKN_-{}-$1 esyscmd(-{python -c "import sys; sys.stdout.write('%d'%ord('$2'))"}-)}-)
divert(0)dnl

Я был бы очень признателен, если бы кто-нибудь знал о лучшем способе сделать это (например, нативный m4 или более переносимая команда оболочки).

В интересах других, заинтересованных в чистой реализации m4, мне удалось создать следующий макрос преобразования. Он должен вмешиваться в символы цитирования, чтобы поддерживать нормальные символы кавычек m4. Это может быть немного упрощено, если это не важно.

changequote(<!,!>) # Change quotes so we can handle "`" and "'"

# Change quotes every time this macro is called
define(<!asciiord!>,<!changequote(<!,!>)<!!>_asciiord(<!$1!>)<!!>changequote`'dnl
!>)

# Convert chars one at a time in the string argument
define(<!_asciiord!>,<!ifelse(<!$1!>,,, dnl
  <!_aconv(substr(<!$1!>,0,1))<!!>ifelse(len(<!$1!>),1,,<!,!>) $0(substr(<!$1!>,1))!>)!>)

# Map ASCII chars to their integer index by position
# Control chars are not supported.
# If the comment character is changed you must alter the map accordingly
define(<!_aconv!>,<!ifelse(<!$1!>,<! !>,32,<!$1!>,<!#!>,35,dnl
  <!index(<!                                 !" $%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !>,<!$1!>)!>)!>)

changequote # Restore normal quoting chars

Использование:

asciiord(`hello') --> 104, 101, 108, 108, 111
Другие вопросы по тегам