|
|
  |
скрипт + gcc |
|
|
|
May 20 2009, 09:14
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045

|
Код #!/bin/sh
COUNT=0
for FILE in *.c do CURR=`cpp -E ${FILE} | grep -vv "^#" | grep "foo(" | grep -vv -c "void foo("` COUNT=`expr ${COUNT} + ${CURR}` echo -e "${FILE}\t:${CURR}\t:${COUNT}" done
cat > foo_call_count.h << EOF #ifndef _FOO_CALL_COUNT_H #define _FOO_CALL_COUNT_H
#define foo_call_count ${COUNT}
#endif /*_FOO_CALL_COUNT_H*/ EOF Ну а дальше, делаете foo_call_count.h зависимым от всех с-файлов и генерируете его при помощи этого скрипта. UPD. Улучшенная версия с предварительной обработкой препроцессором (препроцессор убирает комментарии).
|
|
|
|
|
May 21 2009, 05:45
|
Участник

Группа: Новичок
Сообщений: 22
Регистрация: 20-05-09
Пользователь №: 49 303

|
Спасибо за совет, будем посмотреть
|
|
|
|
|
May 21 2009, 08:23
|
Участник

Группа: Новичок
Сообщений: 22
Регистрация: 20-05-09
Пользователь №: 49 303

|
Цитата(antiwin @ May 21 2009, 09:45)  Спасибо за совет, будем посмотреть Не совсем понятно как формируется выражение CURR=`cpp -E ${FILE} | grep -vv "^#" | grep "foo(" | grep -vv -c "void foo("` Как я понял, последние два оператора проверяют синтаксис на наличие foo, но вот что делают первые два?
|
|
|
|
|
May 22 2009, 06:24
|
Участник

Группа: Новичок
Сообщений: 22
Регистрация: 20-05-09
Пользователь №: 49 303

|
Цитата(antiwin @ May 21 2009, 12:23)  Не совсем понятно как формируется выражение CURR=`cpp -E ${FILE} | grep -vv "^#" | grep "foo(" | grep -vv -c "void foo("` Как я понял, последние два оператора проверяют синтаксис на наличие foo, но не понятно что значит grep -vv , такое сочетание параметров я не нашел нигде. 
|
|
|
|
|
May 25 2009, 07:39
|
Участник

Группа: Новичок
Сообщений: 22
Регистрация: 20-05-09
Пользователь №: 49 303

|
p.s отвечаю не сразу. т.к дома нет инета.
|
|
|
|
|
May 25 2009, 07:47
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045

|
Цитата(antiwin @ May 25 2009, 09:02)  Спасибо, прояснилось. Как я понимаю этот скрипт надо вписать в makefile?. И еще, давно хотел спросить, запись типа #define _FOO_CALL_COUNT_H определяет файл FOO_CALL_COUNT.H, но как препроцессор знает что перед H надо ставить точку. Почему просто не написать #include <FOO_CALL_COUNT.H>  Скрипт лучше поместить в отдельный sh-файл и запускать при необходимости (из мейкфайла) (не уверен но может и из makefile-а работать). Разберем конструкцию по строчкам: 1. #ifndef _FOO_CALL_COUNT_H проверяем не объявлен ли _FOO_CALL_COUNT_H, если не объявлен - п.2. Если обьявлен - значит этот заголовочный файл включен не в первый раз и значит его содержимое можно не обрабатывать. 2. #define _FOO_CALL_COUNT_H Это является стандартным обрамлением для заголовочных файлов. Цитата(Сергей Борщ @ May 25 2009, 10:43)  Кстати, имена, начинающиеся с подчеркивания зарезервированы за компилятором и стандартной библиотекой, во избежание неприятностей свои имена с подчеркивания лучше не начинать. Спасибо за замечание, учту.
|
|
|
|
|
May 25 2009, 11:11
|
Участник

Группа: Новичок
Сообщений: 22
Регистрация: 20-05-09
Пользователь №: 49 303

|
Цитата(Сергей Борщ @ May 25 2009, 11:43)  Определяется символ _FOO_CALL_COUNT_H и дальше идет проверка именно этого символа. Это программист сам для себя решает, что _FOO_CALL_COUNT_H относится к файлу foo_call_count.h. То есть, компилятор у себя в "уме" держит некую таблицу в которой, допустим, строке _FOO_CALL_COUNT_H соответствует include <FOO_CALL_COUNT.H>? Цитата(Сергей Борщ @ May 25 2009, 11:43)  Скрипт лучше поместить в отдельный sh-файл и запускать при необходимости (из мейкфайла). Разберем конструкцию по строчкам: 1. #ifndef _FOO_CALL_COUNT_H проверяем не объявлен ли _FOO_CALL_COUNT_H. Т.е запуск скрипта с помощью команды sh (скрипт)? Хотел бы уточнить выражение (объявлен ли _FOO_CALL_COUNT_H), если следовать синтаксису С, то это запись (_FOO_CALL_COUNT_H FOO_CALL_COUNT.H ) или нет? Мне хотелось бы понять сам механизм.
Сообщение отредактировал antiwin - May 25 2009, 11:28
|
|
|
|
|
May 25 2009, 14:33
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(antiwin @ May 25 2009, 14:11)  То есть, компилятор у себя в "уме" держит некую таблицу в которой, допустим, строке _FOO_CALL_COUNT_H соответствует include <FOO_CALL_COUNT.H>? Нет никакой таблицы. Нет никакого соответствия. вот смотрите: Код foo.h: #ifndef FOO_H_INCLUDED__ #define FOO_H_INCLUDED__ ..... #endif //FOO_H_INCLUDED__
abc.c: #include "foo.h" .... #include "foo.h" Что происходит при компиляции abc.c? 1)удаляются все комментарии. 2)весь текст foo.h вставляется в те места, где был #include "foo.h". Все, #include исчезли, на их месте появился текст. 3) Теперь препроцессор проходит весь файл от начала до конца. В месте, где файл foo.h вставлен первый раз, он встречает строку #ifndef FOO_H_INCLUDED__. 4)Он ищет в своих списках символ FOO_H_INCLUDED__ и не находит его. Символ не определен. Условие выполнилось, препроцессор просматривает текст внутри условия. 5) тут он встречает строку #define FOO_H_INCLUDED__. Он вносит такой символ в свои списки - все, символ определен. 6) он просматривает файл дальше и доходит до места, где был второй #include "foo.h". Тут он снова встречает строку #ifndef FOO_H_INCLUDED__. 7) Он снова смотрит в своих списках и теперь уже находит там символ FOO_H_INCLUDED__. Условие не выполнилось, препроцессор выкидывает весь текст до #endif . Все, содержимое foo.h попало компилятору только один раз. Как мы обозвали этот символ - FOO_H_INCLUDED__ или FOO_H_ или SKIP_THIS_FILE или TIPA_TEST - препроцессору все равно. Это наша забота, чтобы в каждом заголовочном файле был определен уникальный символ. И проще всего это сделать, связав имя символа с именем файла. Чтобы понять смысл выражения "определен символ" - лучше всего прочитать документацию на препроцессор (не компилятор, а именно препроцессор - до компилятора эти символы не доходят).
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 26 2009, 06:27
|
Участник

Группа: Новичок
Сообщений: 22
Регистрация: 20-05-09
Пользователь №: 49 303

|
Цитата(Сергей Борщ @ May 25 2009, 18:33)  Это наша забота, чтобы в каждом заголовочном файле был определен уникальный символ... Я правильно понал, об'явление уникального символа предохраняет от повторной компиляции? А вроде бы у препроцессора есть функции на этот счет? Цитата(Сергей Борщ @ May 25 2009, 18:33)  Он ищет в своих списках символ FOO_H_INCLUDED__ ... Значит, что то вроде таблицы все та ки есть... За ссылку спасибо, как почитаю отпишусь немного отвлеченный вопрос. AT (ADDR (.text) + SIZEOF (.text)) SIZEOF вроде понятно-это размер секции, тогда ADDR-это начало? и что это за оператор AT?. И еще, в WinAvr есть папка с man, как вот эти man прочесть? Я думаю, что масса вопросов сразу бы отпала.
Сообщение отредактировал antiwin - May 26 2009, 06:47
|
|
|
|
|
May 26 2009, 08:13
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(antiwin @ May 26 2009, 09:27)  Я правильно понал, об'явление уникального символа предохраняет от повторной компиляции? А вроде бы у препроцессора есть функции на этот счет? Есть, но они не стандартизованы (насколько я помню) и обладают рядом недостатков. Вот на этом форуме второй ответ описывает их. А обертка из #ifndef #define #endif работает везде. Вот неплохое описаниеЦитата(antiwin @ May 26 2009, 09:27)  Значит, что то вроде таблицы все та ки есть... Как это устроено внутри - не знаю, да это и не принципиально. Важно, что никаких таблиц соответствия имени символа и имени файла нет. Цитата(antiwin @ May 26 2009, 09:27)  немного отвлеченный вопрос. AT (ADDR (.text) + SIZEOF (.text)) Дежа-вю
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 29 2009, 07:49
|
Участник

Группа: Новичок
Сообщений: 22
Регистрация: 20-05-09
Пользователь №: 49 303

|
Привет всем, такой вот проблем: как можно узнать адрес в ОЗУ выше которого стек не "перерастет"? Это нужно сделать на этапе компиляции. И еще, можно ли в теле функции узнать тип возвращаемого значения т.е допустим определена функция void *foo(...), далее где то вызывается int *ptr=foo(...), как в теле foo узнать что это указатель на int?
Сообщение отредактировал antiwin - Jun 29 2009, 08:01
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|