Linux C: Shell-подобная среда - для индивидуального выполнения - команд C? (Переводчик C) - PullRequest
0 голосов
/ 19 ноября 2010

Извините, если вопрос сформулирован неверно - я не знаю правильного слова для того, что я прошу! :)

Скажем, у вас есть простая программа на C, например:

#include <stdio.h>

int main()
{
   int a=2; 
   printf("Hello World %d\n", a);
   return 0;
} 

Как правило, это должно быть сохранено в файле (скажем, hello.c); затем мы запускаем gcc в исходном файле и получаем исполняемый файл - и если мы скомпилировали отладочную информацию, то мы можем использовать gdb в исполняемом файле, чтобы проходить по строкам кода и проверять переменные.

То, что я хотел бы иметь, это в основном своего рода оболочка "C" - похожая на оболочку Python; в том смысле, что я могу иметь последовательность команд Python в файле (скрипт) - или я могу просто вставить те же команды в оболочку, и они будут выполняться одинаково. Что касается простой программы, описанной выше, это то, что я хотел бы сделать (где C> представляет воображаемое приглашение):

C> #include <stdio.h>
(stdio.h included)
C> int a=2;
C> printf("Hello World %d\n", a);
Hello World 2

C> 

Другими словами, я хотел бы иметь возможность выполнять отдельные команды C в интерактивном режиме ( Я предполагаю, что это будет представлять сортировку на лету? ). Первоначально меня вводило в заблуждение название оболочки C (csh) - но я не думаю, что она сможет выполнять команды C на лету.

Итак, прежде всего, я хотел бы знать, можно ли как-то убедить, скажем, gdb действовать таким образом? Если нет, есть ли что-нибудь еще, что позволило бы мне сделать что-то подобное (возможно, какую-то специальную оболочку)?

Что касается контекста - у меня есть некоторый код, где у меня возникают проблемы с устранением неполадок, связанных с указателями между структурами и т. здесь способ gdb может распечатывать структуры работает очень хорошо - однако, чтобы изолировать проблему, я должен создать новые исходные файлы, вставить данные, скомпилировать и снова отладить. В этом случае, я бы предпочел иметь возможность вставить несколько структур (и их команды инициализации) в какую-то оболочку - и затем проверить, используя printf (или даже лучше, что-то похожее на gdb). print) набирается прямо на оболочке.

Просто для протокола - я не особо убежден, что что-то вроде этого действительно существует; но я все равно хотел спросить :)

Заранее спасибо за любые ответы,
Ура!

РЕДАКТИРОВАТЬ : Я был немного занят, поэтому еще не успел просмотреть все ответы для принятия (извините :)); Я просто хотел добавить небольшой комментарий: « интерпретируется против машинного кода »; или как упомянуто @doron:

Проблема с интерактивным запуском исходного кода C / C ++ заключается в том, что компилятор не может выполнять построчную интерпретацию кода.

Я полностью осведомлен об этом - но давайте представим приложение командной строки (может даже интерпретируемое), которое выдает подсказку с интерфейсом командной строки. В начале, давайте предположим, что это приложение генерирует этот простой «текстовый файл» в памяти:

@@HEADER@@

int main()
{
    @@MAIN@@

    return 0;
} 

Затем приложение просто ожидает ввода текста в приглашении и нажатия клавиши ENTER; и по новой строке:

  • Приложение проверяет:
    • если строка начинается с #define или #include, то она добавляется ниже @@HEADER@@ - но выше int main() строки - во временном файле
    • что-нибудь еще, идет ниже @@MAIN@@ строки - но выше return 0; строки - во временном файле
  • временный файл очищается от @@HEADER@@ и @@MAIN@@ строк и сохраняется на диск как temp.c
  • gcc вызывается для компиляции temp.c и генерации temp.out исполняемого файла
    • если не получится, уведомить пользователя, выйти
  • gdb вызывается для запуска исполняемого файла temp.out с точкой останова, установленной в строке return 0;
    • если не получится, уведомить пользователя, выйти
  • выполнение возвращается в подсказку; следующие команды, которые вводит пользователь, фактически передаются в gdb (, поэтому пользователь может использовать такие команды, как p variable для проверки ) - пока пользователь не нажмет, скажем, Ctrl + 1 для выхода gdb
  • Ctrl + 1 - gdb выходит, управление возвращается нашему приложению - которое снова ждет следующей строки кода .. и т. Д.
    • (последующие записи строки кода хранятся во временном файле -находится ниже последней записи из той же категории)

Очевидно, я не ожидал, что смогу вставить весь код ядра Linux в такое приложение, и ожидатьэто сработает :) Однако я ожидал, что смогу вставить через пару struct с и проверить результаты таких утверждений, как, скажем:

char dat = (char) (*(int16_t*)(my->structure->pdata) >> 32 & 0xFF) ^ 0x88; 

... так что я 'Я уверен в том, какой правильный синтаксис использовать (с которым я обычно и сталкиваюсь) - без накладных расходов на перестройку и отладку всего программного обеспечения, просто чтобы выяснить, должен ли я переместить правильную скобкудо или после знака звездочки ( в тех случаях, когда такое действие не приводит к ошибке компиляции, конечно ).

Теперь я не уверен во всем объеме проблем, которые могут возникнуть из-за упрощенной архитектуры приложений, как указано выше.Но это пример, который просто указывает, что что-то вроде «оболочки C» (для относительно простых сессий / программ) было бы концептуально выполнимо, также используя gcc и gdb - без каких-либо серьезных столкновений с, в противном случае,строгое различие между «машинным кодом» и «интерпретируемыми» языками.

Ответы [ 5 ]

6 голосов
/ 19 ноября 2010

Есть интерпретаторы C.
Ищите Ch или CINT.

5 голосов
/ 19 ноября 2010

Редактировать: обнаружена новая ( непроверенная ) вещь, которая, как представляется, требует ОП

c-repl

Или просто используйте его [...] как вождение Ferarri на городских улицах.


Компилятор Tiny C

  • [... поддерживаются многие функции, в том числе]
  • Сценарий C: просто добавьте '#! / usr / local / bin / tcc -run' в первой строке вашего источника C и выполните его непосредственно из командной строки.
2 голосов
/ 19 ноября 2010

Когда ваш процессор запускает компьютерную программу, он запускает то, что называется машинный код. Это серия двоичных инструкций, специфичных для используемого вами процессора. Поскольку машинный код довольно сложен для написания кода, люди изобрели языки более высокого уровня, такие как C и C ++. К сожалению, процессор понимает только машинный код. Так что получается, что мы запускаем компилятор, который преобразует исходный язык высокого уровня в машинный код. Компьютерные языки в этом классе скомпилированы как C и C ++. Говорят, что эти языки работают изначально, поскольку сгенерированный машинный код выполняется ЦП без какой-либо дальнейшей интерпретации.

Теперь некоторые языки, такие как Python, Bash и Perl, не нужно предварительно компилировать, и они скорее интерпретируются. Это означает, что исходный файл читается построчно интерпретатором и выполняется правильное задание для строки. Это дает вам возможность запускать вещи в интерактивной оболочке, как мы видим в Python.

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

1 голос
/ 27 ноября 2010

@ buddhabrot и @pmg - спасибо за ваши ответы!

Для пользы n00bery, вот краткое изложение ответов (так как я не мог сразу понять, что происходит): что яНеобходимый (в OP) обрабатывается так называемым «C Interpreter» ( not a ' C shell '), из которых были предложены следующие:

  • CINT |ROOT - Ubuntu: установить как sudo apt-get install root-system-bin (5.18.00-2.3ubuntu4 + 115 МБ дополнительного дискового пространства)
  • c-repl ( c-repl README ) - Ubuntu: установить как sudo apt-get install c-repl (c-repl_0.0.20071223-1_i386.deb + 106 КБ дополнительного дискового пространства)
  • Ch стандартная версия - стандартная версия бесплатна для Windows/ Unix

Для c-repl - имеется краткое руководство по c-repl homepage в качестве примера сеанса;но вот как ведут себя те же команды в моей системе Ubuntu Lucid с версией репозитория ( edit: см. Где я могу найти документацию c-repl? для лучшего примера ):

$ c-repl 
> int x = 3
> ++x
> .p x
unknown command: p
> printf("%d %p\n", x, &x)
4 0xbbd014
> .t fprintf
repl is ok
> #include <unistd.h>
<stdin>:1:22: warning: extra tokens at end of #include directive
> getp
p getp
No symbol "getp" in current context.
> printf("%d\n", getpid())
10284
> [Ctrl+C]
/usr/bin/c-repl:185:in `readline': Interrupt
    from /usr/bin/c-repl:185:in `input_loop'
    from /usr/bin/c-repl:184:in `loop'
    from /usr/bin/c-repl:184:in `input_loop'
    from /usr/bin/c-repl:203

По-видимому, было бы лучше собрать c-repl из последнего источника.

Для cint было немного трудно найти что-то относящееся к этому напрямую ( веб-страница ссылается на ROOT Tutorials вместо ), но потом яfound " Le Huy: использование интерпретатора CINT - C / C ++ - основные команды ";и вот пример сеанса из моей системы:

(Примечание: если cint недоступен в пакете вашего дистрибутива root-system-bin, попробуйте вместо него root.)

$ cint

cint : C/C++ interpreter  (mailing list 'cint@root.cern.ch')
   Copyright(c) : 1995~2005 Masaharu Goto (gotom@hanno.jp)
   revision     : 5.16.29, Jan 08, 2008 by M.Goto

No main() function found in given source file. Interactive interface started.
'?':help, '.q':quit, 'statement','{statements;}' or '.p [expr]' to evaluate

cint> L iostream
Error: Symbol Liostream is not defined in current scope  (tmpfile):1:
*** Interpreter error recovered ***
cint> {#include <iostream>}
cint> files
Error: Symbol files is not defined in current scope  (tmpfile):1:
*** Interpreter error recovered ***
cint> {int x=3;}
cint> {++x}
Syntax Error: ++x Maybe missing ';' (tmpfile):2:
*** Interpreter error recovered ***
cint> {++x;}
(int)4
cint> .p x
(int)4
cint> printf("%d %p\n", x, &x)
4 0x8d57720
(const int)12
cint> printf("%d\n", getpid())
Error: Function getpid() is not defined in current scope  (tmpfile):1:
*** Interpreter error recovered ***
cint> {#include <unistd.h>}
cint> printf("%d\n", getpid())
10535
(const int)6
cint> .q
  Bye... (try 'qqq' if still running)

В любом случае, это точно , что мне было нужно: возможность загружать заголовки, добавлять переменные и проверять память, которую они займут!Еще раз спасибо всем - Ура!

0 голосов
/ 19 ноября 2010

Python и C относятся к разным видам языка.Python интерпретируется построчно при запуске, но c должен скомпилировать, связать и сгенерировать код для запуска.

...