Например TDA7294

Форум РадиоКот • Просмотр темы - структуры, доступ к "разношерстным" данным через индекс
Форум РадиоКот
Здесь можно немножко помяукать :)





Текущее время: Чт мар 28, 2024 11:21:24

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 15 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: структуры, доступ к "разношерстным" данным через индекс
СообщениеДобавлено: Пт фев 12, 2021 08:53:27 
Вымогатель припоя
Аватар пользователя

Карма: 5
Рейтинг сообщений: 10
Зарегистрирован: Ср дек 08, 2010 19:03:17
Сообщений: 513
Рейтинг сообщения: 0
день добрый!

краткое описание задачи:

1. есть некая структура, с несколькими полями (пока они одного типа, но, для общего решения, пусть они будут разнотипные)

2. нужно со всеми полями структуры провести однотипные и, возможно рекурсивные, задачи ("рекурсия_по_полю"), для простоты опишем эту задачу так:
- нам прислали ящик яблок
- ого! но мы можем съесть за раз только одно
- отправляем сами себе же посылку с одним яблоком
- ого! нам прислали ящик с одним яблоком, наш размерчик, лопаем, благодарим отправителя, требуем продолжения банкета!
- и так, пока не сожрем всю посылку

(конкретика для этой задачи не важна, тема топика дальше)

3. подобные задачи нужно будет сделать со всеми полями структуры по порядку
4. т.к. задачи "однотипные", то вполне логична "рекурсия_по_структуре"
5. можно решить тупо в лоб, написать кучу функций, реализующих обработку каждого поля, и вызывать весь этот паровоз последовательно, один за другим...

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

т.е. реализовать обработку в одной функции, а к полям обращаться по индексу

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

Код:
p_void = ( ((void*)p_void) + shift ); *( (uint8_t  *)p_void) = ((i+1)*10);  // i-й элемент

вот тут
Код:
(uint8_t  *)p_void)


я так понимаю, "массив_типов" создать не получиться :о)

ну... кидайтесь помидорами, идеями, мымслями

спасибо

Код:
avr-gcc, С-only, linux, etc...


Код:
#include <util/delay.h>

#include "main.h"
#include "lib/prn.h"    // prn-lib()

#define SIZE_STRUCT   3
#define SIZE_8        1 // (sizeof int8_t ) // не нашел набегом...
#define SIZE_16       2 // (sizeof int16_t)
#define SIZE_32       4 // (sizeof int32_t)

uint8_t size[SIZE_STRUCT] = {SIZE_8, SIZE_16, SIZE_32};

typedef struct
{
uint8_t  a;
uint16_t b;
uint32_t c;
} t;

typedef t* p;

t test  ; // экземпляр структуры
p p_test; // указатель на структуру

////////////////////////////////////////////////////////////////////////////////
void prn_struct(int8_t i)
////////////////////////////////////////////////////////////////////////////////
{
prn("--- %i \n", i);
prn("test.a = %u \n", test.a);
prn("test.b = %u \n", test.b);
prn("test.c = %lu\n", test.c);
}
////////////////////////////////////////////////////////////////////////////////
int main(void)
////////////////////////////////////////////////////////////////////////////////
{
void* p_void;
prn_init();
prn("### struct ###\n");

p_test = &test;

p_test->a = 1;
p_test->b = 2;
p_test->c = 3;
prn_struct(1);


/*/
// var.1 доступ к "одношерстным" данным
//
*(((uint8_t*)p_test) + 0) = 4;
*(((uint8_t*)p_test) + 1) = 5;
*(((uint8_t*)p_test) + 2) = 6;
prn_struct(2); //*/

//
// var.2 доступ к "разношерстным" данным
//
*( (uint8_t *) (((void*)p_test)                                     ) ) = 4; // 1й элемент
*( (uint16_t*) (((void*)p_test) + sizeof(uint8_t)                   ) ) = 5; // 2й элемент
*( (uint32_t*) (((void*)p_test) + sizeof(uint8_t) + sizeof(uint16_t)) ) = 6; // 3й элемент
prn_struct(3); //*/

//
// var.3 доступ к "разношерстным" данным
//
p_void = (((void*)p_test));

p_void = (((void*)p_void)                   ); *( (uint8_t  *)p_void) = 7;  // 1й элемент
p_void = (((void*)p_void) + sizeof(uint8_t )); *( (uint16_t *)p_void) = 8;  // 2й элемент
p_void = (((void*)p_void) + sizeof(uint16_t)); *( (uint32_t *)p_void) = 9;  // 3й элемент
prn_struct(4); //*/

//
// var.4 доступ к "разношерстным" данным через индекс
//
int8_t i, shift;
p_void = (((void*)p_test));

for(i=0; i<3; i++)
  {
  if(i<=0) { shift = 0        ; } // реализация сдвига
  else     { shift = size[i-1]; }

  p_void = ( ((void*)p_void) + shift ); *( (uint8_t  *)p_void) = ((i+1)*10);  // i-й элемент
  }
prn_struct(5); //*/

return 0;
}
////////////////////////////////////////////////////////////////////////////////



для "одношерстных" данных можно упростить
Код:
for(i=0; i<3; i++)
  {
  *( (uint8_t*) (((void*)p_test) + i) ) = ((i+1)*10+6); // i-й элемент
  }

_________________
Енот - это кот, только инкогнито!
p.s. держитесь обоими руками, а то прорвет...


Последний раз редактировалось sunjob Пт фев 12, 2021 18:13:51, всего редактировалось 2 раз(а).

Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: структуры, доступ к "разношерстным" данным через индекс
СообщениеДобавлено: Пт фев 12, 2021 10:04:04 
Поставщик валерьянки для Кота

Карма: 12
Рейтинг сообщений: 532
Зарегистрирован: Ср июл 17, 2013 13:55:57
Сообщений: 1978
Рейтинг сообщения: 0
Я правильно понимаю - хочется одинаково "пройтись" по всей структуре, содержащей разные типы? Ес-но придется в обработчике вручную учитывать типы. На Си. На C++14 пишут можно шаблонами решить органично: https://github.com/CppCon/CppCon2016/bl ... 202016.pdf

На чистом Си для упрощения задачи, чтобы не писать эту кучу разношерстных кастов, можно данные одного типа группировать в массивы внутри структуры. "5 яблок uint8_t, 3 яблока uint16_t и 2 яблока uint32_t".


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: структуры, доступ к "разношерстным" данным через индекс
СообщениеДобавлено: Пт фев 12, 2021 10:41:20 
Вымогатель припоя
Аватар пользователя

Карма: 5
Рейтинг сообщений: 10
Зарегистрирован: Ср дек 08, 2010 19:03:17
Сообщений: 513
Рейтинг сообщения: 0
1. на СИ
2. стуктура внешняя, без изменений (и задача пока решается в общем случае! последний код - есть решение для случая с одношерстыми данными)
3. судя по предложенному коду
Код:
"5 яблок uint8_t, 3 яблока uint16_t и 2 яблока uint32_t".

задачу не совсем поняли... :))

попробую обьяснить еще раз

1. имеется N полей
2. каждое поле должно "обсчитаться"
3. приходит посылка с "большим количеством яблок" для каждого поля (внешний цикл), (т.е. куча посылок, 1я посылка для поля 1, 2я посылка для поля 2, 3я посылка...)
4. для каждого поля посылка разбивается на посылки с одним яблоком, и вызывает рекурсия "самому себе"
5. и так "разбор" посылок для каждого поля

...

так-то, текущая задача достаточно проста, с одним типом данных и, поэтому, внешний цикл вызовов уже реализован (тот самый последний код)

просто, для тренировки усов, лап и хвостов... решил потренироваться "на разношерстных котах" :)))

ну ... т.е. пока не вижу решения :)) ... или уточните ваши идеи

спасибо

_________________
Енот - это кот, только инкогнито!
p.s. держитесь обоими руками, а то прорвет...


Вернуться наверх
 
PCBWay - всего $5 за 10 печатных плат, первый заказ для новых клиентов БЕСПЛАТЕН

Сборка печатных плат от $30 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Онлайн просмотровщик Gerber-файлов от PCBWay + Услуги 3D печати
Не в сети
 Заголовок сообщения: Re: структуры, доступ к "разношерстным" данным через индекс
СообщениеДобавлено: Пт фев 12, 2021 12:03:00 
Поставщик валерьянки для Кота

Карма: 12
Рейтинг сообщений: 532
Зарегистрирован: Ср июл 17, 2013 13:55:57
Сообщений: 1978
Рейтинг сообщения: 0
Давайте без яблок. Я выше написал - "Я правильно понимаю - хочется одинаково "пройтись" по всей структуре, содержащей разные типы?" - это так? Если так, то ответ там уже был дан. На чистом Си невозможно пройтись итеративно по всей структуре с разными типами данных, не описывая в коде логику работы с этими типами данных. Т.е. как бы универсально написать так, что скажем к каждому элементу структуры прибавлялось бы 1, внезависимости от размерности и типов данных структуры - не получится. Логика кода ("внешний цикл") должен знать, с чем он работает.
Как альтернативу, для упрощения написания этой логики, я предложил группировать данные в структуре по типам.


Вернуться наверх
 
Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: структуры, доступ к "разношерстным" данным через индекс
СообщениеДобавлено: Пт фев 12, 2021 12:47:14 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2057
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18024
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
в GCC есть макрос offsetof, который позволяет обратиться к полю структуре по смещению этого поля, зная начало структуры. т.е. не по имени поля обращаться, а по его относительному адресу в памяти. таким образом, можно в функцию передавать значение этого макроса и внутри функции абсолютно однотипно обсчитывать любые поля.

я верно понял, что вы хотите?

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

скушно, бабоньки!


Вернуться наверх
 
Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: структуры, доступ к "разношерстным" данным через индекс
СообщениеДобавлено: Пт фев 12, 2021 13:00:54 
Вымогатель припоя
Аватар пользователя

Карма: 5
Рейтинг сообщений: 10
Зарегистрирован: Ср дек 08, 2010 19:03:17
Сообщений: 513
Рейтинг сообщения: 0
to NStorm
Цитата:
внезависимости от размерности и типов данных структуры - не получится

-> если опустить некоторые моменты :)) не совсем красиво, но все в одном месте, уже и это плюс :wink:
Код:
...
// var.4 доступ к "разношерстным" данным через индекс
...
switch(i)
  {
  case   0 : p_void = ( ((void*)p_void) + shift ); *( (uint8_t  *)p_void) = ((i+1)*10); break;
  case   1 : p_void = ( ((void*)p_void) + shift ); *( (uint16_t  *)p_void) = ((i+1)*10); break;
  case   2 : p_void = ( ((void*)p_void) + shift ); *( (uint32_t  *)p_void) = ((i+1)*10); break;
  }



...

to ARV
Цитата:
...обратиться к полю структуре по смещению этого поля, зная начало структуры. т.е. не по имени поля обращаться, а по его относительному адресу в памяти...

так и сделано

Цитата:
в GCC есть макрос offsetof + таким образом, можно в функцию передавать значение этого макроса и внутри функции абсолютно однотипно обсчитывать любые поля.

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

Цитата:
внутри функции абсолютно однотипно обсчитывать любые поля

с макросом еще не разбирался, с помощью него обращение к полям через индекс?

...

Offset

6.53 Support for offsetof

GCC implements for both C and C++ a syntactic extension to implement the offsetof macro.

Код:
primary:
        "__builtin_offsetof" "(" typename "," offsetof_member_designator ")"

offsetof_member_designator:
          identifier
        | offsetof_member_designator "." identifier
        | offsetof_member_designator "[" expr "]"

This extension is sufficient such that

Код:
#define offsetof(type, member)  __builtin_offsetof (type, member)


is a suitable definition of the offsetof macro. In C++, type may be dependent. In either case, member may consist of a single identifier, or a sequence of member accesses and array references.

...

гм.. эге... мур... не, бля, точно муррр...
я столько не выкурю :)))
придется почитать, что пишут по этому поводу бывалые коты и фугля... мугля ... гугля... да, точно гугля!

зы: спасибо

_________________
Енот - это кот, только инкогнито!
p.s. держитесь обоими руками, а то прорвет...


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: структуры, доступ к "разношерстным" данным через индекс
СообщениеДобавлено: Сб фев 13, 2021 06:32:32 
Это не хвост, это антенна

Карма: 4
Рейтинг сообщений: 141
Зарегистрирован: Ср июн 25, 2008 15:19:44
Сообщений: 1382
Рейтинг сообщения: 0
Какая то нереальная задача. Каждая структура обрабатывается соответственно. Хоть полями, хоть кусочками байтами. Универсальности нет. И не выдумывайте лишнего.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: структуры, доступ к "разношерстным" данным через индекс
СообщениеДобавлено: Сб фев 13, 2021 08:00:49 
Вымогатель припоя
Аватар пользователя

Карма: 5
Рейтинг сообщений: 10
Зарегистрирован: Ср дек 08, 2010 19:03:17
Сообщений: 513
Рейтинг сообщения: 0
на изилектрониксе предложили хитрый ход конскими ушами :)))

Цитата:
я так понимаю, "массив_типов" создать не получиться :о)

->
Код:
struct types{
uint8_t _t0;
uint16_t _t1;
uint32_t _t2;
};

#define TYPE(n) typeof(types._t##n)


срочно надо попробовать :write:

...

ну а пока очевидный педальный способ (причесал код из топика...:o)))
Код:
//
// var.4 через индекс / switch (mod)
//
p_void = (((void*)p_test));

for(i=0; i<3; i++)
  {
  switch(i) // выбор, по "соответствующему типу"
    {
    case   0 : *( (uint8_t  *)p_void) = (256-1       ); break;
    case   1 : *( (uint16_t *)p_void) = (65536-1     ); break;
    case   2 : *( (uint32_t *)p_void) = (4294967296-1); break;
    }

  p_void = ( ((void*)p_void) + size[i] ); // сдвиг указателя "с опозданием" (то, что нужно :о)
  }

prn_struct(4); //*/

_________________
Енот - это кот, только инкогнито!
p.s. держитесь обоими руками, а то прорвет...


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: структуры, доступ к "разношерстным" данным через индекс
СообщениеДобавлено: Сб фев 13, 2021 12:14:13 
Это не хвост, это антенна

Карма: 4
Рейтинг сообщений: 141
Зарегистрирован: Ср июн 25, 2008 15:19:44
Сообщений: 1382
Рейтинг сообщения: 0
Ничего нового не увидел. И вы только что своими руками доказали, универсальности нет. Свитч кейс, кстати, первое, что мне в голову пришло. Сам так делал неоднократно. Но с индексом не заморачивался. Выхлоп больше получается.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: структуры, доступ к "разношерстным" данным через индекс
СообщениеДобавлено: Сб фев 13, 2021 17:28:56 
Вымогатель припоя
Аватар пользователя

Карма: 5
Рейтинг сообщений: 10
Зарегистрирован: Ср дек 08, 2010 19:03:17
Сообщений: 513
Рейтинг сообщения: 0
Цитата:
Ничего нового не увидел

калейдоскоп купите! :)))

...

ВСЕМ, кто по делу, ОГРОМНОЕ СПАСИБО!

пока непонимание по поводу "подсказки"
Код:
#define TYPE(n) ...

_________________
Енот - это кот, только инкогнито!
p.s. держитесь обоими руками, а то прорвет...


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: структуры, доступ к "разношерстным" данным через индекс
СообщениеДобавлено: Вс фев 14, 2021 12:06:01 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2057
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18024
Откуда: Новочеркасск
Рейтинг сообщения: 4
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
все универсальные решения на поверку оказываютс во-первых, не универсальными, а во-вторых, громоздкими.
что касается доступа к полям структуры по индексу, т.е. по номеру поля, то напрашивается следующее универсальное решение
1. обращаться будем при помощи "универсальной" функции
Код:
void something(const field id, void *rec, rec_type *rectype){
   int32_t field; // сюда поместим значение поля
   field = rectype[id].func(rec + rectype[id].offset);
   // дальше делаем с этим field то, что нужно
}

первый параметр - номер поля, второй - адрес структуры, третий - адрес массива, в котором описаны поля этой структуры
2. поля структуры описываются так:
Код:
typedef int32_t (value*)(void*); // тип описания функции, возвращающей значение поля
typedef struct{
  uint8_t offset; // смещение пол относительно начала структуры
  value func; // функция, которая вернет значение поля
} rec_type;

3. создаем функции для полей разных типов. и тут первая проблема "универсальности" - только целочисленные значения могут быть возвращены. float, например, уже не укладывается в концепцию.
Код:
int32_t get_byte(char *ptr){
  return *ptr;
}

int32_t get_int(int *ptr){
  return *ptr;
}
// и так далее для всех вариантов полей, которые могут быть приведены к целочисленному значению

4. создаем и инициализируем массивы описаний разных структур, делая такми способом заготовки для обращения по индексу.
5. ну, а далее - обращаемся к полям по индексам...

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

мой опыт программирования позволяет мне утверждать, что выход тут только один - отказаться от НЕНУЖНОЙ универсальности, т.е. переформулировать задание и/или алгоритм так, чтобы необходимости в такой "универсальности" не возникало.

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

скушно, бабоньки!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: структуры, доступ к "разношерстным" данным через индекс
СообщениеДобавлено: Пт фев 26, 2021 21:25:15 
Первый раз сказал Мяу!
Аватар пользователя

Карма: 3
Рейтинг сообщений: 19
Зарегистрирован: Чт май 14, 2015 16:58:00
Сообщений: 35
Откуда: Kharkiv
Рейтинг сообщения: 1
- нам прислали ящик яблок
- ого! но мы можем съесть за раз только одно
- отправляем сами себе же посылку с одним яблоком
- ого! нам прислали ящик с одним яблоком, наш размерчик, лопаем, благодарим отправителя, требуем продолжения банкета!
- и так, пока не сожрем всю посылку

Думал не подвернется случай... :)
Вложение:
Apple.jpg [23.4 KiB]
Скачиваний: 120


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: структуры, доступ к "разношерстным" данным через индекс
СообщениеДобавлено: Сб фев 27, 2021 15:18:34 
Вымогатель припоя
Аватар пользователя

Карма: 5
Рейтинг сообщений: 10
Зарегистрирован: Ср дек 08, 2010 19:03:17
Сообщений: 513
Рейтинг сообщения: 0
да...но там задачка-то еще упрощённо описана... есть еще и "морды", которые будут жрать эти яблоки... :о)

_________________
Енот - это кот, только инкогнито!
p.s. держитесь обоими руками, а то прорвет...


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: структуры, доступ к "разношерстным" данным через индекс
СообщениеДобавлено: Чт мар 18, 2021 20:59:21 
Встал на лапы
Аватар пользователя

Карма: 1
Рейтинг сообщений: -1
Зарегистрирован: Пн окт 31, 2016 06:23:19
Сообщений: 93
Рейтинг сообщения: 0
с макросом еще не разбирался, с помощью него обращение к полям через индекс?


Непонятно, зачем вы заостряете внимание на каком-то "обращении через индекс". Обращение через индекс, то есть определение положения очередного поля в памяти, никакого труда не представляет и легко реализуется через таблицу смещений с помощью того же `offsetof` (которое есть не "в GCC", как тут сбивающе с толку написали, а является хрестоматийной классикой стандартного языка С, то есть к GCC как таковому не имеет никакого отношения вообще).

Проблема то не в "обращении по индексу". Проблема в том, что каждое поле может иметь свой тип и требовать своей собственной обработки. Тут, очевидно, можно выкрутиться через таблицу обработчиков, принимающих `void *` и уже внутри знающих, что делать со своими полями и какой тип они имеют.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: структуры, доступ к "разношерстным" данным через индекс
СообщениеДобавлено: Вс апр 18, 2021 06:26:03 
Вымогатель припоя
Аватар пользователя

Карма: 5
Рейтинг сообщений: 10
Зарегистрирован: Ср дек 08, 2010 19:03:17
Сообщений: 513
Рейтинг сообщения: 0
Цитата:
... Тут, очевидно, можно выкрутиться через таблицу обработчиков, принимающих `void *` и уже внутри знающих, что делать со своими полями и какой тип они имеют...


так и сделано, только проще и нагляднее :)))

_________________
Енот - это кот, только инкогнито!
p.s. держитесь обоими руками, а то прорвет...


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 15 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: Greenpeace и гости: 23


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y